Issues (5)

src/AbstractService.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Promopult\TikTokMarketingApi;
6
7
use GuzzleHttp\Psr7\Request;
8
use Promopult\TikTokMarketingApi\Exception\ErrorResponse;
9
use Promopult\TikTokMarketingApi\Exception\MalformedResponse;
10
use Psr\Http\Client\ClientInterface;
11
use Psr\Http\Message\RequestInterface;
12
use Psr\Http\Message\ResponseInterface;
13
14
abstract class AbstractService implements ServiceInterface
15
{
16
    use RequestSenderTrait;
17
18
    protected CredentialsInterface $credentials;
19
    protected ClientInterface $httpClient;
20
21
    public function __construct(
22
        CredentialsInterface $credentials,
23
        ClientInterface $httpClient
24
    ) {
25
        $this->credentials = $credentials;
26
        $this->httpClient = $httpClient;
27
    }
28
29
    public function requestApi(
30
        string $httpMethod,
31
        string $endpoint,
32
        array $args = []
33
    ): array {
34
        $httpMethod = strtolower($httpMethod);
35
36
        $args = array_filter($args);
37
38
        $url = $this->credentials->getApiBaseUrl() . $endpoint;
39
40
        if ($args && $httpMethod === 'get') {
0 ignored issues
show
Bug Best Practice introduced by
The expression $args 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...
41
            $url .= '?' . $this->prepareGetParams($args);
42
        }
43
44
        $headers = [
45
            'Content-Type' => 'application/json',
46
            'Accept' => 'application/json',
47
        ];
48
49
        if (!empty($this->credentials->getAccessToken())) {
50
            $headers['Access-Token'] = $this->credentials->getAccessToken();
51
        }
52
53
        $body = $httpMethod === 'get' || empty($args)
54
            ? null
55
            : \json_encode($args, JSON_THROW_ON_ERROR);
56
57
        $request = new Request(
58
            $httpMethod,
59
            $url,
60
            $headers,
61
            $body
62
        );
63
64
        $response = $this->sendRequest($request);
65
66
        return $this->handleResponse($response, $request);
67
    }
68
69
    /**
70
     * @throws \JsonException
71
     */
72
    protected function handleResponse(
73
        ResponseInterface $response,
74
        RequestInterface $request
75
    ): array {
76
        /** @var array $decodedJson */
77
        $decodedJson = \json_decode(
78
            (string) $response->getBody(),
79
            true,
80
            512,
81
            JSON_THROW_ON_ERROR
82
        );
83
84
        if (!isset($decodedJson['code'])) {
85
            throw new MalformedResponse(
86
                $request,
87
                $response
88
            );
89
        }
90
91
        if ($decodedJson['code'] != 0) {
92
            throw new ErrorResponse(
93
                (int) $decodedJson['code'],
94
                (string) ($decodedJson['message'] ?? 'Unknown error.'),
95
                $request,
96
                $response
97
            );
98
        }
99
100
        return $decodedJson;
101
    }
102
103
    protected function prepareGetParams(array $args): string
104
    {
105
        $formedArgs = [];
106
107
        /**
108
         * @psalm-suppress MixedAssignment
109
         */
110
        foreach ($args as $arg => $value) {
111
            if (is_scalar($value)) {
112
                $formedArgs[$arg] = $value;
113
            }
114
115
            if (is_array($value)) {
116
                $formedArgs[$arg] = \json_encode(array_filter($value));
117
            }
118
        }
119
120
        return http_build_query($formedArgs);
121
    }
122
}
123