Completed
Push — master ( 316baf...2178d1 )
by Raffael
67:25 queued 62:39
created

AbstractRest::getRequestOptions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 6
cts 6
cp 1
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * tubee.io
7
 *
8
 * @copyright   Copryright (c) 2017-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Tubee\Endpoint;
13
14
use GuzzleHttp\Client;
15
use InvalidArgumentException;
16
use Psr\Log\LoggerInterface;
17
use Tubee\AttributeMap\AttributeMapInterface;
18
use Tubee\Collection\CollectionInterface;
19
use Tubee\Endpoint\Rest\Exception as RestException;
20
use Tubee\Workflow\Factory as WorkflowFactory;
21
22
abstract class AbstractRest extends AbstractEndpoint
23
{
24
    /**
25
     * Guzzle client.
26
     *
27
     * @var Client
28
     */
29
    protected $client;
30
31
    /**
32
     * Container.
33
     *
34
     * @var string
35
     */
36
    protected $container;
37
38
    /**
39
     * Access token.
40
     *
41
     * @var string
42
     */
43
    protected $access_token;
44
45
    /**
46
     * Init endpoint.
47
     */
48 9
    public function __construct(string $name, string $type, Client $client, CollectionInterface $collection, WorkflowFactory $workflow, LoggerInterface $logger, array $resource = [])
49
    {
50 9
        $this->client = $client;
51 9
        parent::__construct($name, $type, $collection, $workflow, $logger, $resource);
52 9
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 3
    public function setup(bool $simulate = false): EndpointInterface
58
    {
59 3
        if (isset($this->resource['data']['resource']['auth']) && $this->resource['data']['resource']['auth'] === 'oauth2') {
60 2
            $oauth = $this->resource['data']['resource']['oauth2'];
61
62 2
            $this->logger->debug('fetch access_token from ['.$oauth['token_endpoint'].']', [
63 2
                'category' => get_class($this),
64
            ]);
65
66 2
            $response = $this->client->post($oauth['token_endpoint'], [
67
                'form_params' => [
68 2
                    'grant_type' => 'client_credentials',
69 2
                    'client_id' => $oauth['client_id'],
70 2
                    'client_secret' => $oauth['client_secret'],
71 2
                    'scope' => $oauth['scope'],
72
                ],
73
            ]);
74
75 2
            $this->logger->debug('fetch access_token ended with status ['.$response->getStatusCode().']', [
76 2
                'category' => get_class($this),
77
            ]);
78
79 2
            $body = json_decode($response->getBody()->getContents(), true);
80
81 2
            if (isset($body['access_token'])) {
82 1
                $this->access_token = $body['access_token'];
83
            } else {
84 1
                throw new RestException\AccessTokenNotAvailable('No access_token in token_endpoint response');
85
            }
86
        }
87
88 2
        $response = $this->client->get('', $this->getRequestOptions());
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
89
90 2
        return $this;
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function change(AttributeMapInterface $map, array $diff, array $object, array $endpoint_object, bool $simulate = false): ?string
97
    {
98
        $uri = $this->client->getConfig('base_uri').'/'.$this->getResourceId($endpoint_object);
99
        $this->logger->info('update rest object on endpoint ['.$this->getIdentifier().'] using [PATCH] to ['.$uri.']', [
100
            'category' => get_class($this),
101
        ]);
102
103
        if ($simulate === false) {
104
            $result = $this->client->patch($uri, $this->getRequestOptions([
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
105
                'json' => $diff,
106
            ]));
107
        }
108
109
        return null;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function delete(AttributeMapInterface $map, array $object, array $endpoint_object, bool $simulate = false): bool
116
    {
117
        $uri = $this->client->getConfig('base_uri').'/'.$this->getResourceId($endpoint_object);
118
        $this->logger->info('delete object from endpoint ['.$this->getIdentifier().'] using DELETE to ['.$uri.']', [
119
            'category' => get_class($this),
120
        ]);
121
122
        if ($simulate === false) {
123
            $response = $this->client->delete($uri, $this->getRequestOptions());
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
124
        }
125
126
        return true;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function create(AttributeMapInterface $map, array $object, bool $simulate = false): ?string
133
    {
134
        $this->logger->info('create new object on endpoint ['.$this->getIdentifier().'] using POST to ['.$this->client->getConfig('base_uri').']', [
135
            'category' => get_class($this),
136
        ]);
137
138
        if ($simulate === false) {
139
            $result = $this->client->post('', $this->getRequestOptions([
140
                'json' => $object,
141
            ]));
142
143
            $body = json_decode($result->getBody()->getContents(), true);
144
145
            return $this->getResourceId($body);
146
        }
147
148
        return null;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function getDiff(AttributeMapInterface $map, array $diff): array
155
    {
156
        $result = [];
157
        foreach ($diff as $attribute => $update) {
158
            switch ($update['action']) {
159
                case AttributeMapInterface::ACTION_REPLACE:
160
                case AttributeMapInterface::ACTION_ADD:
161
                    $result[$attribute] = $update['value'];
162
163
                break;
164
                case AttributeMapInterface::ACTION_REMOVE:
165
                    $result[$attribute] = null;
166
167
                break;
168
                default:
169
                    throw new InvalidArgumentException('unknown diff action '.$update['action'].' given');
170
            }
171
        }
172
173
        return $result;
174
    }
175
176
    /**
177
     * Verify response.
178
     */
179 3
    protected function getResponse($response): array
180
    {
181 3
        $data = json_decode($response->getBody()->getContents(), true);
182
183 3
        $this->logger->debug('request to ['.$this->client->getConfig('base_uri').'] ended with code ['.$response->getStatusCode().']', [
184 3
            'category' => get_class($this),
185
        ]);
186
187 3
        if (isset($this->container)) {
188 3
            if (isset($data[$this->container])) {
189 3
                $data = $data[$this->container];
190
            } else {
191
                throw new RestException\InvalidContainer('specified container '.$this->container.' does not exists in response');
192
            }
193
        }
194
195 3
        if (!is_array($data)) {
196
            throw new Exception\NotIterable('response is not iterable');
197
        }
198
199 3
        return $data;
200
    }
201
202
    /**
203
     * Get headers.
204
     */
205 5
    protected function getRequestOptions(array $options = []): array
206
    {
207 5
        if ($this->access_token) {
208 1
            return array_merge($options, [
209
                'headers' => [
210 1
                    'Accept' => 'application/json',
211 1
                    'Authorization' => "Bearer {$this->access_token}",
212
                ],
213
            ]);
214
        }
215
216 4
        return $options;
217
    }
218
219
    /**
220
     * Get identifier.
221
     */
222
    protected function getResourceId(array $object): string
223
    {
224
        if (isset($object[$this->identifier])) {
225
            return $object[$this->identifier];
226
        }
227
228
        throw new RestException\IdNotFound('attribute '.$this->identifier.' is not available');
229
    }
230
}
231