Test Failed
Branch develop (1e6d78)
by Ludwig
02:24
created

Client::call()   B

Complexity

Conditions 9
Paths 10

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 20
nc 10
nop 6
dl 0
loc 34
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the CwdPowerDNS Client
5
 *
6
 * (c) 2018 cwd.at GmbH <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cwd\PowerDNSClient;
15
16
use Doctrine\Common\Annotations\AnnotationReader;
17
use GuzzleHttp\Psr7\Request;
18
use Http\Discovery\HttpClientDiscovery;
19
use Symfony\Component\PropertyAccess\PropertyAccessor;
20
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
21
use Symfony\Component\Serializer\Encoder\JsonEncoder;
22
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
23
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
24
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
25
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
26
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
27
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
28
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
29
use Symfony\Component\Serializer\Serializer;
30
use GuzzleHttp\Client as GuzzleClient;
31
32
class Client
33
{
34
    private $basePath = 'api/v1';
35
    private $apiKey;
36
37
    private $apiUri;
38
39
    /** @var GuzzleClient */
40
    private $client;
41
42
    /** @var Serializer */
43
    private $serializer;
44
45
    public function __construct($apiHost, $apiKey, ?GuzzleClient $client = null)
46
    {
47
        $this->apiKey = $apiKey;
48
        $this->apiUri = sprintf('%s/%s', $apiHost, $this->basePath);
49
        if (null === $client) {
50
            //$this->client  = new GuzzleClient(['base_uri' => $this->apiUri]);
51
            $this->client = HttpClientDiscovery::find();
0 ignored issues
show
Documentation Bug introduced by
It seems like Http\Discovery\HttpClientDiscovery::find() of type Http\Client\HttpClient is incompatible with the declared type GuzzleHttp\Client of property $client.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
52
        }
53
54
        $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
55
        $discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
56
57
        $normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter(), new PropertyAccessor(), new ReflectionExtractor(), $discriminator);
58
        $this->serializer = new Serializer([new DateTimeNormalizer(), new ArrayDenormalizer(), $normalizer], ['json' => new JsonEncoder()]);
59
    }
60
61
    /**
62
     * @param string|null     $payload
63
     * @param int|string|null $id
64
     * @param string          $endpoint
65
     * @param string|null     $hydrationClass
66
     * @param bool            $isList
67
     * @param string          $method
68
     *
69
     * @throws \Http\Client\Exception
70
     * @throws \LogicException
71
     *
72
     * @return mixed
73
     */
74
    public function call($payload = null, $uri, $hydrationClass = null, $isList = false, $method = 'GET', array $queryParams = [])
75
    {
76
        $uri = rtrim(sprintf('%s/%s', $this->apiUri, $uri), '/');
77
78
        if (count($queryParams) > 0) {
79
            $uri .= '?'.http_build_query($queryParams);
80
        }
81
82
        $request = new Request($method, $uri, [
83
            'X-API-Key' => $this->apiKey,
84
            'Content-Type' => 'application/json',
85
        ], $payload);
86
87
        $response = $this->client->sendRequest($request);
88
89
        $responseBody = $response->getBody()->getContents();
0 ignored issues
show
Bug introduced by
The method getBody() does not exist on GuzzleHttp\Promise\PromiseInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
        $responseBody = $response->/** @scrutinizer ignore-call */ getBody()->getContents();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
90
        $responseData = json_decode($responseBody);
91
92
        if ($response->getStatusCode() >= 300 && isset($responseData->error)) {
0 ignored issues
show
Bug introduced by
The method getStatusCode() does not exist on GuzzleHttp\Promise\PromiseInterface. Did you maybe mean getState()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

92
        if ($response->/** @scrutinizer ignore-call */ getStatusCode() >= 300 && isset($responseData->error)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
93
            throw new \LogicException(sprintf('Error on %s request %s: %s', $method, $uri, $responseData->error));
94
        }
95
        if ($response->getStatusCode() >= 300) {
96
            $message = isset($responseData->message) ?? 'Unknown';
97
            throw new \Exception(sprintf('Error on request %s: %s', $response->getStatusCode(), $message));
98
        }
99
100
        if (null !== $hydrationClass && class_exists($hydrationClass)) {
101
            return $this->denormalizeObject($hydrationClass, $responseData, $isList);
102
        }
103
        if (null !== $hydrationClass && !class_exists($hydrationClass)) {
104
            throw new \Exception(sprintf('HydrationClass (%s) does not exist', $hydrationClass));
105
        }
106
107
        return $responseData;
108
    }
109
110
    public function denormalizeObject($hydrationClass, $dataObject, $isList = false)
111
    {
112
        if (!$isList) {
113
            $dataObject = [$dataObject];
114
        }
115
116
        $result = [];
117
118
        foreach ($dataObject as $data) {
119
            $result[] = $this->serializer->denormalize($data, $hydrationClass, null, [
120
                ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT => false,
121
            ]);
122
        }
123
124
        if ($isList) {
125
            return $result;
126
        }
127
128
        return current($result);
129
    }
130
131
    /**
132
     * @return Serializer
133
     */
134
    public function getSerializer(): Serializer
135
    {
136
        return $this->serializer;
137
    }
138
}
139