Completed
Pull Request — master (#5)
by
unknown
01:14
created

AirtableApiClient::jsonToObject()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Tapp\Airtable\Api;
4
5
use GuzzleHttp\Client;
6
use Illuminate\Support\Str;
7
8
class AirtableApiClient implements ApiClient
9
{
10
    private $client;
11
12
    private $base;
13
    private $table;
14
15
    private $filters = [];
16
    private $pageSize = 100;
17
    private $maxRecords = 100;
18
19
    public function __construct($base, $table, $access_token, Client $client = null)
20
    {
21
        $this->base = $base;
22
        $this->table = $table;
23
        $this->client = $client ?? $this->buildClient($access_token) ;
24
    }
25
26
    private function buildClient($access_token)
27
    {
28
        $stack = \GuzzleHttp\HandlerStack::create();
29
        $stack->push(
30
            \GuzzleHttp\Middleware::log(
31
                new \Monolog\Logger('Logger'),
32
                new \GuzzleHttp\MessageFormatter('{request} >>> {res_body}')
33
            )
34
        );
35
36
        return new Client([
37
            'base_uri' => 'https://api.airtable.com',
38
            'headers' => [
39
                'Authorization' => "Bearer {$access_token}",
40
                'content-type' => 'application/json',
41
            ],
42
            // uncomment to log requests
43
            'handler' => $stack,
44
        ]);
45
    }
46
47
    public function where($column, $value)
48
    {
49
        $this->filters [] = "{{$column}}=\"{$value}\"";
50
51
        return $this;
52
    }
53
54
    public function table($table)
55
    {
56
        $this->table = $table;
57
58
        return $this;
59
    }
60
61
    public function firstOrCreate(array $idData, array $createData = [])
62
    {
63
        foreach ($idData as $key => $value) {
64
            $this->where($key, $value);
65
        }
66
67
        $results = $this->get();
68
69
        // first
70
        if ($results->isNotEmpty()) {
71
            return $results->first();
72
        }
73
74
        // create
75
        $data = array_merge($idData, $createData);
76
77
        return $this->post($data);
78
    }
79
80
    public function createOrUpdate(array $idData, array $updateData = [])
0 ignored issues
show
Unused Code introduced by
The parameter $updateData is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
81
    {
82
        foreach ($idData as $key => $value) {
83
            $this->where($key, $value);
84
        }
85
86
        $results = $this->get();
87
88
        // first
89
        if ($results->isNotEmpty()) {
90
            return $results->first();
91
        }
92
93
        // create
94
        $data = array_merge($idData, $createData);
0 ignored issues
show
Bug introduced by
The variable $createData does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
95
96
        return $this->post($data);
97
    }
98
99
    public function get(?string $id = null)
100
    {
101
        $url = $this->getEndpointUrl($id);
102
103
        return $this->jsonToArray($this->client->get($url));
104
    }
105
106
    public function getAllPages()
107
    {
108
        $url = $this->getEndpointUrl();
109
110
        $response = $this->client->get($url, [
111
            'query' => [
112
                'pageSize' => $this->pageSize,
113
                'maxRecords' => $this->maxRecords,
114
            ],
115
        ]);
116
117
        //TODO: loop through offset to get more than one page when more than 100 records exist
118
119
        return $this->jsonToObject($response);
120
    }
121
122
    public function post($contents = null)
123
    {
124
        $url = $this->getEndpointUrl();
125
126
        $params = ['json' => ['fields' => (object) $contents]];
127
128
        return $this->jsonToArray($this->client->post($url, $params));
129
    }
130
131
    public function put(string $id, $contents = null)
132
    {
133
        $url = $this->getEndpointUrl($id);
134
135
        $params = ['json' => ['fields' => (object) $contents]];
136
137
        return $this->jsonToObject($this->client->put($url, $params));
138
    }
139
140
    public function patch(string $id, $contents = null)
141
    {
142
        $url = $this->getEndpointUrl($id);
143
144
        $params = ['json' => ['fields' => (object) $contents]];
145
146
        return $this->jsonToObject($this->client->patch($url, $params));
147
    }
148
149
    public function delete(string $id)
150
    {
151
        $url = $this->getEndpointUrl($id);
152
153
        return $this->jsonToObject($this->client->delete($url));
154
    }
155
156
    public function responseToJson($response)
157
    {
158
        $body = (string) $response->getBody();
159
160
        return $body;
161
    }
162
163
    public function jsonToObject($response)
164
    {
165
        $body = (string) $response->getBody();
166
167
        if ($body === '') {
168
            return collect([]);
169
        }
170
171
        $object = json_decode($body);
172
173
        return isset($object->records) ? collect($object->records) : $object;
174
    }
175
176
    public function jsonToArray($response)
177
    {
178
        $body = (string) $response->getBody();
179
180
        if ($body === '') {
181
            return [];
182
        }
183
184
        return json_decode($body, true);
185
    }
186
187
    protected function getEndpointUrl(?string $id = null): string
188
    {
189
        if ($id) {
190
            $url = '/v0/~/~/~';
191
192
            return Str::replaceArray('~', [
193
                $this->base,
194
                $this->table,
195
                $id,
196
            ], $url);
197
        }
198
199
        $url = '/v0/~/~';
200
201
        $url = Str::replaceArray('~', [
202
            $this->base,
203
            $this->table
204
        ], $url);
205
206
        if ($this->filters) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->filters of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
207
            $url .= '?' . http_build_query([
208
                'filterByFormula' => implode('&', $this->filters),
209
            ]);
210
        }
211
212
        return $url;
213
    }
214
}
215