Endpoint::setParent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Ipag\Sdk\Core;
4
5
use Ipag\Sdk\Exception\HttpClientException;
6
use Ipag\Sdk\Http\Response;
7
use Ipag\Sdk\IO\SerializerInterface;
8
use Ipag\Sdk\Path\CompositePathInterface;
9
use Ipag\Sdk\Util\ArrayUtil;
10
use Ipag\Sdk\Util\PathUtil;
11
12
abstract class Endpoint implements CompositePathInterface
13
{
14
    protected Client $client;
15
    protected CompositePathInterface $parent;
16
    protected ?SerializerInterface $serializer;
17
    protected string $location;
18
19
    public function __construct(Client $client, CompositePathInterface $parent, ?string $location = null, ?SerializerInterface $serializer = null)
20
    {
21
        $this->client = $client;
22
        $this->parent = $parent;
23
        $this->location = $this->location ?? $location;
24
        $this->serializer = $serializer;
25
    }
26
27
    //
28
29
    protected function _GET(array $query = [], array $header = [], ?string $relativeUrl = null): Response
30
    {
31
        return $this->request(__FUNCTION__, null, $query, $header, $relativeUrl);
32
    }
33
34
    protected function _POST($body, array $query = [], array $header = [], ?string $relativeUrl = null): Response
35
    {
36
        return $this->request(__FUNCTION__, $body, $query, $header, $relativeUrl);
37
    }
38
39
    protected function _PUT($body, array $query = [], array $header = [], ?string $relativeUrl = null): Response
40
    {
41
        return $this->request(__FUNCTION__, $body, $query, $header, $relativeUrl);
42
    }
43
44
    protected function _PATCH($body, array $query = [], array $header = [], ?string $relativeUrl = null): Response
45
    {
46
        return $this->request(__FUNCTION__, $body, $query, $header, $relativeUrl);
47
    }
48
49
    protected function _DELETE(array $query = [], array $header = [], ?string $relativeUrl = null): Response
50
    {
51
        return $this->request(__FUNCTION__, null, $query, $header, $relativeUrl);
52
    }
53
54
    protected function _HEAD(array $query = [], array $header = [], ?string $relativeUrl = null): Response
55
    {
56
        return $this->request(__FUNCTION__, null, $query, $header, $relativeUrl);
57
    }
58
59
    //
60
61
    protected function request(string $method, $body, array $query = [], array $header = [], ?string $relativeUrl = null): Response
62
    {
63
        try {
64
            return $this->client->request(
65
                strtoupper(substr($method, 1)),
66
                $relativeUrl ? $this->joinPath($relativeUrl) : $this->getPath(),
67
                $body,
68
                $query,
69
                $header,
70
                $this->serializer
71
            );
72
        } catch (HttpClientException $e) {
73
74
            $errorsSanitized = $this->sanitizeErrorMessage($e->getResponse());
0 ignored issues
show
Bug introduced by
It seems like $e->getResponse() can also be of type null; however, parameter $response of Ipag\Sdk\Core\Endpoint::sanitizeErrorMessage() does only seem to accept Ipag\Sdk\Http\Response, maybe add an additional type check? ( Ignorable by Annotation )

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

74
            $errorsSanitized = $this->sanitizeErrorMessage(/** @scrutinizer ignore-type */ $e->getResponse());
Loading history...
75
76
            $this->exceptionThrown(
77
                new HttpClientException(
78
                    'response message: ' . json_encode(implode(' | ', $errorsSanitized)) . " (status code: {$e->getCode()})",
0 ignored issues
show
Bug introduced by
It seems like $errorsSanitized can also be of type null; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

78
                    'response message: ' . json_encode(implode(' | ', /** @scrutinizer ignore-type */ $errorsSanitized)) . " (status code: {$e->getCode()})",
Loading history...
79
                    $e->getCode(),
80
                    $e,
81
                    $e->getResponse(),
82
                    null,
83
                    null,
84
                    $errorsSanitized
85
                )
86
            );
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Ipag\Sdk\Http\Response. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
87
88
        } catch (\Throwable $th) {
89
            $this->exceptionThrown($th);
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Ipag\Sdk\Http\Response. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
90
        }
91
    }
92
93
    //
94
95
    public function getParent(): ?CompositePathInterface
96
    {
97
        return $this->parent;
98
    }
99
100
    public function setParent(?CompositePathInterface $parent): void
101
    {
102
        $this->parent = $parent;
103
    }
104
105
    public function getPath(): string
106
    {
107
        return $this->getParent()->joinPath($this->location);
108
    }
109
110
    public function joinPath(string $relative): string
111
    {
112
        return implode(PathUtil::PATH_SEPARATOR, [$this->getPath(), ltrim($relative, PathUtil::PATH_SEPARATOR)]);
113
    }
114
115
    //
116
117
    public static function make(Client $client, CompositePathInterface $parent, ?string $location = null, ?SerializerInterface $serializer = null)
118
    {
119
        return new static($client, $parent, $location, $serializer);
120
    }
121
122
    protected function exceptionThrown(\Throwable $e): void
123
    {
124
        throw $e;
125
    }
126
127
    private function sanitizeErrorMessage(Response $response): ?array
128
    {
129
        $responseData = $response->getParsedPath('message');
130
131
        if (is_string($responseData))
0 ignored issues
show
introduced by
The condition is_string($responseData) is always false.
Loading history...
132
            return [$responseData];
133
134
        if (is_array($responseData))
135
            return ArrayUtil::extractStrings($responseData);
136
137
        $responseData = $response->getParsedPath('error');
138
139
        if (is_array($responseData))
140
            return ArrayUtil::extractStrings($responseData);
141
142
        $responseData = $response->getParsedPath('data');
143
144
        if (is_array($responseData))
145
            return ArrayUtil::extractStrings($responseData);
146
    }
147
148
}