• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PiteurStudio / CourierDZ / 13103483584

02 Feb 2025 11:27PM UTC coverage: 26.042%. Remained the same
13103483584

push

github

web-flow
Merge pull request #10 from n4ss1m/refactor_rector

Refactor: Enable Rector Rules for Code Quality and Strictness

13 of 56 new or added lines in 7 files covered. (23.21%)

100 of 384 relevant lines covered (26.04%)

3.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/ProviderIntegrations/YalidineProviderIntegration.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace CourierDZ\ProviderIntegrations;
6

7
use CourierDZ\Contracts\ShippingProviderContract;
8
use CourierDZ\Exceptions\CreateOrderException;
9
use CourierDZ\Exceptions\CredentialsException;
10
use CourierDZ\Exceptions\HttpException;
11
use CourierDZ\Exceptions\TrackingIdNotFoundException;
12
use CourierDZ\Support\ShippingProviderValidation;
13
use GuzzleHttp\Client;
14
use GuzzleHttp\Exception\GuzzleException;
15
use GuzzleHttp\Psr7\Request;
16

17
abstract class YalidineProviderIntegration implements ShippingProviderContract
18
{
19
    use ShippingProviderValidation;
20

21
    /**
22
     * Provider credentials
23
     *
24
     * @var array<non-empty-string, non-empty-string>
25
     */
26
    protected array $credentials;
27

28
    /**
29
     * Validation rules for creating an order
30
     *
31
     * @var array<non-empty-string, non-empty-string>
32
     */
33
    public array $getCreateOrderValidationRules = [
34
        'order_id' => 'required|string',
35
        'from_wilaya_name' => 'required|string',
36
        'firstname' => 'required|string',
37
        'familyname' => 'required|string',
38
        'contact_phone' => 'required|string',
39
        'address' => 'required|string',
40
        'to_commune_name' => 'required|string',
41
        'to_wilaya_name' => 'required|string',
42
        'product_list' => 'required|array',
43
        'Price' => 'required|numeric|min:0|max:150000',
44
        'do_insurance' => 'required|boolean',
45
        'declared_value' => 'required|numeric|min:0|max:150000',
46
        'Length' => 'required|numeric|min:0',
47
        'Width' => 'required|numeric|min:0',
48
        'Height' => 'required|numeric|min:0',
49
        'Weight' => 'required|numeric|min:0',
50
        'freeshipping' => 'required|boolean',
51
        'is_stopdesk' => 'required|boolean',
52
        'stopdesk_id' => 'required_if:is_stopdesk,true|string',
53
        'has_exchange' => 'required|boolean',
54
        'product_to_collect' => 'required|boolean',
55
    ];
56

57
    /**
58
     * Constructor
59
     *
60
     * @param  array<non-empty-string, non-empty-string>  $credentials  The provider credentials
61
     *
62
     * @throws CredentialsException
63
     */
64
    public function __construct(array $credentials)
65
    {
66
        // Get the provider name from the metadata
67
        $provider_name = static::metadata()['name'];
×
68

69
        // Check if the credentials are valid
70
        if (! isset($credentials['id']) || ! isset($credentials['token'])) {
×
71
            throw new CredentialsException($provider_name.' credentials must include "id" and "token".');
×
72
        }
73

74
        // Set the credentials
75
        $this->credentials = $credentials;
×
76
    }
77

78
    /**
79
     * Get provider metadata
80
     */
81
    abstract public static function metadata(): array;
82

83
    /**
84
     * Get the API domain
85
     */
86
    abstract public static function apiDomain(): string;
87

88
    /**
89
     * Test credentials
90
     *
91
     * Makes a GET request to the /wilayas endpoint to check if the credentials are valid.
92
     * If the request is successful (200 status code), the credentials are valid.
93
     * If the request returns a 401 or 500 status code, the credentials are invalid.
94
     * Any other status code is considered an unexpected error.
95
     *
96
     * @throws HttpException
97
     */
98
    public function testCredentials(): bool
99
    {
100
        try {
101
            // Initialize Guzzle client
102
            $client = new Client(['http_errors' => false]);
×
103

104
            // Define the headers
105
            $headers = [
×
106
                'X-API-ID' => $this->credentials['id'],
×
107
                'X-API-TOKEN' => $this->credentials['token'],
×
108
            ];
×
109

110
            // Make the GET request
111
            $response = $client->request('GET', static::apiDomain().'/v1/wilayas/', [
×
112
                'headers' => $headers,
×
113
            ]);
×
114

115
            // If the request is successful, the credentials are valid
116
            if ($response->getStatusCode() === 200) {
×
117
                return true;
×
118
            }
119

120
            // If the request returns a 401 or 500 status code, the credentials are invalid
121
            if (in_array($response->getStatusCode(), [401, 500])) {
×
122
                return false;
×
123
            }
124

125
            // Any other status code is considered an unexpected error
126
            throw new HttpException('Yalidine, Unexpected error occurred.');
×
NEW
127
        } catch (GuzzleException $guzzleException) {
×
128
            // Handle exceptions
NEW
129
            throw new HttpException($guzzleException->getMessage());
×
130
        }
131
    }
132

133
    /**
134
     * Get rates
135
     *
136
     * @param  int  $from_wilaya_id
137
     * @param  int  $to_wilaya_id
138
     *
139
     * @throws HttpException
140
     */
141
    public function getRates($from_wilaya_id, $to_wilaya_id): array
142
    {
143
        try {
144
            // Initialize Guzzle client
145
            $client = new Client(['http_errors' => false]);
×
146

147
            // Define the headers
148
            $headers = [
×
149
                'X-API-ID' => $this->credentials['id'],
×
150
                'X-API-TOKEN' => $this->credentials['token'],
×
151
            ];
×
152

153
            // Make the GET request
154
            $response = $client->request('GET', static::apiDomain().'/v1/fees/?from_wilaya_id='.$from_wilaya_id.'&to_wilaya_id='.$to_wilaya_id, [
×
155
                'headers' => $headers,
×
156
            ]);
×
157

158
            // Return the response body as an array
159
            return json_decode($response->getBody()->getContents(), true);
×
160

NEW
161
        } catch (GuzzleException $guzzleException) {
×
162
            // Handle exceptions
NEW
163
            throw new HttpException($guzzleException->getMessage());
×
164
        }
165
    }
166

167
    public function getCreateOrderValidationRules(): array
168
    {
169
        return $this->getCreateOrderValidationRules;
×
170
    }
171

172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function createOrder(array $orderData): array
176
    {
177
        $this->validateCreate($orderData);
×
178

179
        try {
180
            // Initialize Guzzle client
181
            $client = new Client;
×
182

183
            // Define the headers
184
            $headers = [
×
185
                'X-API-ID' => $this->credentials['id'],
×
186
                'X-API-TOKEN' => $this->credentials['token'],
×
187
                'Content-Type' => 'application/json',
×
188
            ];
×
189

190
            $requestBody = json_encode([$orderData], JSON_UNESCAPED_UNICODE);
×
191

192
            if ($requestBody === false) {
×
193
                throw new CreateOrderException('Create Order failed : JSON encoding error');
×
194
            }
195

196
            $request = new Request('POST', static::apiDomain().'/v1/parcels/', $headers, $requestBody);
×
197

198
            $response = $client->send($request);
×
199

200
            // Get the response body
201
            $body = $response->getBody()->getContents();
×
202

203
            $arrayResponse = json_decode($body, true);
×
204

205
            $message = $arrayResponse[$orderData['id']]['message'];
×
206

207
            // Check if the order creation was successful
208
            if ($arrayResponse[$orderData['id']]['status'] !== 'true') {
×
209
                throw new CreateOrderException('Create Order failed ( `'.$message.'` ) : '.implode(' ', $arrayResponse[$orderData['id']]));
×
210
            }
211

212
            // Return the created order
213
            return $arrayResponse[$orderData['id']];
×
214

NEW
215
        } catch (GuzzleException $guzzleException) {
×
216
            // Handle exceptions
NEW
217
            throw new HttpException($guzzleException->getMessage());
×
218
        }
219
    }
220

221
    /**
222
     * {@inheritdoc}
223
     */
224
    public function orderLabel(string $orderId): array
225
    {
226
        // Get order details
227
        $order = $this->getOrder($orderId);
×
228

229
        // Return the label URL as an associative array
230
        return [
×
231
            'type' => 'url',
×
232
            'data' => $order['label'],
×
233
        ];
×
234
    }
235

236
    /**
237
     * Read order details
238
     *
239
     * @throws HttpException
240
     * @throws TrackingIdNotFoundException
241
     */
242
    public function getOrder(string $trackingId): array
243
    {
244
        try {
245
            // Initialize Guzzle client
246
            $client = new Client(['http_errors' => false]);
×
247

248
            // Define the headers
249
            $headers = [
×
250
                'X-API-ID' => $this->credentials['id'],
×
251
                'X-API-TOKEN' => $this->credentials['token'],
×
252
            ];
×
253

254
            // Make the GET request
255
            $response = $client->request('GET', 'https://api.yalidine.app/v1/parcels/'.$trackingId, [
×
256
                'headers' => $headers,
×
257
            ]);
×
258

259
            $data = json_decode($response->getBody()->getContents(), true);
×
260

261
            if ($data['total_data'] == 0) {
×
262
                throw new TrackingIdNotFoundException('Tracking ID not found : '.$trackingId.' , Provider : Yalidine');
×
263
            }
264

265
            return $data['data'][0];
×
266

NEW
267
        } catch (GuzzleException $guzzleException) {
×
268
            // Handle exceptions
NEW
269
            throw new HttpException($guzzleException->getMessage());
×
270
        }
271
    }
272
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc