Passed
Push — main ( 417efa...3246f4 )
by Vasil
02:26
created

EcontAdapter::jsonDecode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace VasilDakov\Shipping\Adapter;
6
7
use GuzzleHttp\Client;
8
use Laminas\Diactoros\RequestFactory;
9
use Psr\Http\Client\ClientExceptionInterface;
10
use VasilDakov\Econt\Configuration;
0 ignored issues
show
Bug introduced by
The type VasilDakov\Econt\Configuration was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use VasilDakov\Econt\Econt;
12
use VasilDakov\Econt\EcontInterface;
13
use VasilDakov\Econt\Request\GetCitiesRequest;
0 ignored issues
show
Bug introduced by
The type VasilDakov\Econt\Request\GetCitiesRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use VasilDakov\Shipping\Model\City;
15
use VasilDakov\Shipping\Model\Country;
16
use VasilDakov\Shipping\Request;
17
use VasilDakov\Shipping\Response;
18
use Selective\Transformer\ArrayTransformer;
19
20
use function array_filter;
21
use function str_starts_with;
22
23
class EcontAdapter implements AdapterInterface
24
{
25
    private const NAME = 'Econt';
26
27
    private ?EcontInterface $client;
28
29 4
    public function __construct(?EcontInterface $client = null)
30
    {
31 4
        if (! $client) {
32 1
            $configuration = new Configuration(
33 1
                username: $_ENV['ECONT_USERNAME'],
34 1
                password: $_ENV['ECONT_PASSWORD'],
35 1
            );
36
37 1
            $client = new Econt(
38 1
                $configuration,
39 1
                new Client(
40 1
                    [
41 1
                        'connect_timeout' => 5,
42 1
                        'read_timeout' => 10,
43 1
                        'verify' => false,
44 1
                    ]
45 1
                ),
46 1
                new RequestFactory()
47 1
            );
48
        }
49
50 4
        $this->client = $client;
51
    }
52
53
54 3
    private function jsonDecode(string $json): array
55
    {
56 3
        return json_decode($json, true);
57
    }
58
59
    /**
60
     * @throws ClientExceptionInterface
61
     */
62
    public function getClientProfiles(): string
63
    {
64
        return $this->client->getClientProfiles();
0 ignored issues
show
Bug introduced by
The method getClientProfiles() does not exist on null. ( Ignorable by Annotation )

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

64
        return $this->client->/** @scrutinizer ignore-call */ getClientProfiles();

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...
65
    }
66
67
68
    /**
69
     * @param Request\GetCountriesRequest $request
70
     * @return Response\GetCountriesResponse
71
     * @throws ClientExceptionInterface
72
     */
73 3
    public function getCountries(Request\GetCountriesRequest $request): Response\GetCountriesResponse
74
    {
75 3
        $json = $this->client->getCountries();
76 3
        $data = $this->jsonDecode($json);
77
78
        // transform properties to Shipping Model
79 3
        $transformer = new ArrayTransformer();
80 3
        $transformer
81 3
            ->map('id', 'id')
82 3
            ->map('name', 'name')
83 3
            ->map('nameEn', 'nameEn')
84 3
            ->map('isoAlpha2', 'code2')
85 3
            ->map('isoAlpha3', 'code3')
86 3
        ;
87 3
        $result = [];
88 3
        foreach ($data['countries'] as $country) {
89 3
            $result['countries'][] = $transformer->toArray($country);
90
        }
91
92
        // $hydrator = new \Laminas\Hydrator\ClassMethodsHydrator();
93
        // $hydrator = new \Laminas\Hydrator\ObjectPropertyHydrator();
94
        // $hydrator = new \Laminas\Hydrator\ReflectionHydrator();
95
96 3
        $strategy = new \Laminas\Hydrator\Strategy\CollectionStrategy(
97 3
            new \Laminas\Hydrator\ObjectPropertyHydrator(),
98 3
            Country::class
99 3
        );
100 3
        $array = $strategy->hydrate($result['countries']);
101
102
        // implementing missing econt non-strict country search
103 3
        if (null !== $request->name) {
104 1
            $array = array_filter($array, function (Country $country) use ($request) {
105 1
                return
106 1
                    str_starts_with($country->name, $request->name) ||
0 ignored issues
show
Bug introduced by
It seems like $country->name can also be of type null; however, parameter $haystack of str_starts_with() does only seem to accept string, 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

106
                    str_starts_with(/** @scrutinizer ignore-type */ $country->name, $request->name) ||
Loading history...
Bug introduced by
It seems like $request->name can also be of type null; however, parameter $needle of str_starts_with() does only seem to accept string, 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

106
                    str_starts_with($country->name, /** @scrutinizer ignore-type */ $request->name) ||
Loading history...
107 1
                    str_starts_with($country->nameEn, $request->name)
108 1
                ;
109 1
            });
110
        }
111
112 3
        return new Response\GetCountriesResponse($array);
113
    }
114
115
116
    /**
117
     * @param Request\GetCitiesRequest $request
118
     * @return Response\GetCitiesResponse
119
     * @throws ClientExceptionInterface
120
     */
121
    public function getCities(Request\GetCitiesRequest $request): Response\GetCitiesResponse
122
    {
123
        $json = $this->client->getCities(new GetCitiesRequest(countryCode: $request->isoAlpha3));
124
125
        $data = $this->jsonDecode($json);
126
127
        // transform properties to Shipping Model
128
        $transformer = new ArrayTransformer();
129
        $transformer
130
            ->map('id', 'id')
131
            ->map('country', 'country')
132
            ->map('postCode', 'postCode')
133
            ->map('name', 'name')
134
            ->map('nameEn', 'nameEn')
135
        ;
136
        $result = [];
137
        foreach ($data['cities'] as $country) {
138
            $result['cities'][] = $transformer->toArray($country);
139
        }
140
141
        $hydrator = new \Laminas\Hydrator\ObjectPropertyHydrator();
142
        $strategy = new \Laminas\Hydrator\Strategy\CollectionStrategy(
143
            $hydrator,
144
            City::class
145
        );
146
        $hydrator->addStrategy(
147
            'country',
148
            new \Laminas\Hydrator\Strategy\HydratorStrategy(
149
                new \Laminas\Hydrator\ReflectionHydrator(),
150
                Country::class
151
            )
152
        );
153
154
        $array = $strategy->hydrate($result['cities']);
155
156
        if (null !== $request->name) {
157
            $array = array_filter($array, function (City $city) use ($request) {
158
                return
159
                    str_starts_with($city->name, $request->name) ||
0 ignored issues
show
Bug introduced by
It seems like $request->name can also be of type null; however, parameter $needle of str_starts_with() does only seem to accept string, 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

159
                    str_starts_with($city->name, /** @scrutinizer ignore-type */ $request->name) ||
Loading history...
Bug introduced by
It seems like $city->name can also be of type null; however, parameter $haystack of str_starts_with() does only seem to accept string, 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

159
                    str_starts_with(/** @scrutinizer ignore-type */ $city->name, $request->name) ||
Loading history...
160
                    str_starts_with($city->nameEn, $request->name)
161
                    ;
162
            });
163
        }
164
165
        return new Response\GetCitiesResponse($array);
166
    }
167
168
    /**
169
     */
170
    public function getOffices(array $data): string
171
    {
172
        return $this->client->getOffices($data);
0 ignored issues
show
Bug introduced by
$data of type array is incompatible with the type VasilDakov\Econt\Request\GetOfficesRequest expected by parameter $object of VasilDakov\Econt\EcontInterface::getOffices(). ( Ignorable by Annotation )

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

172
        return $this->client->getOffices(/** @scrutinizer ignore-type */ $data);
Loading history...
173
    }
174
175
    public function calculate()
176
    {
177
        return $this->client->calculate();
0 ignored issues
show
Bug introduced by
The method calculate() does not exist on VasilDakov\Econt\EcontInterface. ( Ignorable by Annotation )

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

177
        return $this->client->/** @scrutinizer ignore-call */ calculate();

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...
178
    }
179
180
    public function track(array $data)
181
    {
182
        return $this->client->getShipmentStatuses($data);
183
    }
184
185
    public function getName(): string
186
    {
187
        return self::NAME;
188
    }
189
}
190