• 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

62.07
/src/Services/ShippingService.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace CourierDZ\Services;
6

7
use CourierDZ\Contracts\ShippingProviderContract;
8
use CourierDZ\Exceptions\InvalidProviderException;
9

10
class ShippingService
11
{
12
    private readonly ShippingProviderContract $shippingProviderContract;
13

14
    /**
15
     * Create a new ShippingService instance for the given provider.
16
     *
17
     * @param  non-empty-string  $providerName  The name of the shipping provider (e.g. "ZR Express", "Procolis", etc.)
18
     * @param  array<non-empty-string, non-empty-string>  $credentials  An array of credentials for the provider (e.g. API key, username, password, etc.)
19
     *
20
     * @throws InvalidProviderException If the provider is not valid
21
     */
22
    public function __construct(string $providerName, array $credentials)
23
    {
24
        $this->shippingProviderContract = $this->loadProvider($providerName, $credentials);
36✔
25
    }
26

27
    /**
28
     * Load the provider class.
29
     *
30
     * This method takes a provider name and credentials and checks if the provider exists.
31
     * If the provider does not exist, it throws an InvalidProviderException.
32
     * If the provider exists but does not implement ShippingProviderContract
33
     * or extend XyzProviderIntegration, it throws an InvalidProviderException.
34
     *
35
     * @param  non-empty-string  $providerName  The name of the shipping provider (e.g. "ZR Express", "Procolis", etc.)
36
     * @param  array<non-empty-string, non-empty-string>  $credentials  An array of credentials for the provider (e.g. API key, username, password, etc.)
37
     * @return ShippingProviderContract The provider class instance
38
     *
39
     * @throws InvalidProviderException If the provider is not valid
40
     */
41
    private function loadProvider(string $providerName, array $credentials): ShippingProviderContract
42
    {
43
        $namespace = sprintf('CourierDZ\ShippingProviders\%sProvider', $providerName);
36✔
44

45
        if (! class_exists($namespace)) {
36✔
46
            // If the provider class does not exist, throw an exception
47
            // with a list of available providers
48
            $availableProvidersNames = '';
×
49
            foreach (self::getProviders() as $provider) {
×
50
                $availableProvidersNames .= $provider['name'].', ';
×
51
            }
52

NEW
53
            throw new InvalidProviderException(sprintf('Incorrect `%s` Shipping provider name, Available providers are: ', $providerName).rtrim($availableProvidersNames, ', '));
×
54
        }
55

56
        // Create an instance of the provider class
57
        // and check if it implements ShippingProviderContract
58
        // or extends XyzProviderIntegration
59
        $providerClass = new $namespace($credentials);
36✔
60

61
        if (! $providerClass instanceof ShippingProviderContract) {
24✔
NEW
62
            throw new InvalidProviderException($providerName.'Provider must implement ShippingProviderContract or extend XyzProviderIntegration.');
×
63
        }
64

65
        return $providerClass;
24✔
66
    }
67

68
    /**
69
     * Check if the credentials are valid for the current shipping provider.
70
     *
71
     * This method delegates the credential validation to the provider's
72
     * implementation of the testCredentials method.
73
     *
74
     * @return bool True if the credentials are valid, false otherwise.
75
     */
76
    public function testCredentials(): bool
77
    {
78
        // Call the provider's testCredentials method to verify the credentials.
NEW
79
        return $this->shippingProviderContract->testCredentials();
×
80
    }
81

82
    /**
83
     * get the creation validation rules.
84
     *
85
     * @return array<non-empty-string, non-empty-string|array<int, non-empty-string>> The validation rules for creating an order
86
     */
87
    public function getCreateOrderValidationRules(): array
88
    {
89
        return $this->shippingProviderContract->getCreateOrderValidationRules();
6✔
90
    }
91

92
    /**
93
     * Validate the order creation data.
94
     *
95
     * This method delegates the validation of the order data
96
     * to the provider's implementation of the validateCreate method.
97
     *
98
     * @param  array<non-empty-string, non-empty-string>  $orderData  The order data to validate
99
     * @return bool True if the order data is valid, false otherwise
100
     */
101
    public function validateCreate(array $orderData): bool
102
    {
103
        // Call the provider's validateCreate method to validate the order data
NEW
104
        return $this->shippingProviderContract->validateCreate($orderData);
×
105
    }
106

107
    /**
108
     * Get shipping rates for every wilaya or for a specific wilaya.
109
     *
110
     * @param  int<1, 58>|null  $from_wilaya_id  The ID of the wilaya to get rates from
111
     * @param  int<1, 58>|null  $to_wilaya_id  The ID of the wilaya to get rates to
112
     * @return array<int , mixed> An array of shipping rates, each containing the price, and wilaya IDs
113
     */
114
    public function getRates(?int $from_wilaya_id = null, ?int $to_wilaya_id = null): array
115
    {
NEW
116
        return $this->shippingProviderContract->getRates($from_wilaya_id, $to_wilaya_id);
×
117
    }
118

119
    /**
120
     * Create a new order.
121
     *
122
     * This method delegates the order creation to the provider's
123
     * implementation of the createOrder method.
124
     *
125
     * @param  array<non-empty-string, mixed>  $orderData  The order data to create an order with
126
     * @return array<non-empty-string, mixed> An array containing the order ID and the tracking ID
127
     */
128
    public function createOrder(array $orderData): array
129
    {
130
        return $this->shippingProviderContract->createOrder($orderData);
6✔
131
    }
132

133
    /**
134
     * Read an order by its tracking ID.
135
     *
136
     * This method delegates the order retrieval to the provider's
137
     * implementation of the getOrder method.
138
     *
139
     * @param  non-empty-string  $trackingId  The tracking ID of the order to retrieve
140
     * @return array<non-empty-string, mixed> An array containing the order details
141
     */
142
    public function getOrder(string $trackingId): array
143
    {
NEW
144
        return $this->shippingProviderContract->getOrder($trackingId);
×
145
    }
146

147
    /**
148
     * Retrieve the label for a specific order.
149
     *
150
     * This method delegates the task to the provider's implementation of the
151
     * orderLabel method, which returns the label details for the given order ID.
152
     *
153
     * @param  non-empty-string  $orderId  The ID of the order for which to retrieve the label.
154
     * @return array{type: 'pdf'|'url', data: non-empty-string} An array containing the label details of the order.
155
     */
156
    public function orderLabel(string $orderId): array
157
    {
158
        // Delegate to the provider's orderLabel method to get the order label
NEW
159
        return $this->shippingProviderContract->orderLabel($orderId);
×
160
    }
161

162
    //    /**
163
    //     * Cancel an order.
164
    //     *
165
    //     * This method delegates the cancellation of an order to the provider's
166
    //     * implementation of the cancelOrder method.
167
    //     *
168
    //     * @param  string  $orderId  The ID of the order to be canceled.
169
    //     * @return bool True if the order was successfully canceled, false otherwise.
170
    //     */
171
    //    public function cancelOrder(string $orderId): bool
172
    //    {
173
    //        // Delegate the cancellation to the provider's cancelOrder method
174
    //        return $this->provider->cancelOrder($orderId);
175
    //    }
176

177
    /**
178
     * Get metadata for the provider.
179
     *
180
     * This method is called by the ShippingService to retrieve metadata about
181
     * the current provider.
182
     *
183
     * @return array<non-empty-string, non-empty-string|null> An array containing metadata of the provider
184
     */
185
    public function metaData(): array
186
    {
187
        return $this->shippingProviderContract->metaData();
6✔
188
    }
189

190
    /**
191
     * Get a list of all available providers with metadata.
192
     *
193
     * This method reads the contents of the ShippingProviders directory and
194
     * loads every provider class that implements the ShippingProviderContract.
195
     * It then calls the metaData method on each provider to get the
196
     * provider's metadata and returns an array of all the metadata.
197
     *
198
     * @return array<int , array<non-empty-string, non-empty-string|null>> An array containing the metadata for all available providers.
199
     */
200
    public static function getProviders(): array
201
    {
202
        $providers = [];
12✔
203

204
        $providers_filenames = glob(__DIR__.'/../ShippingProviders/*Provider.php');
12✔
205

206
        if ($providers_filenames === false) {
12✔
NEW
207
            $providers_filenames = [];
×
208
        }
209

210
        foreach ($providers_filenames as $provider_filename) {
12✔
211
            $className = basename($provider_filename, '.php');
12✔
212
            $namespace = 'CourierDZ\ShippingProviders\\'.$className;
12✔
213

214
            // Check if the class exists and implements the ShippingProviderContract
215
            if (class_exists($namespace) && is_subclass_of($namespace, ShippingProviderContract::class)) {
12✔
216
                // Get the metadata for the provider
217
                $providers[] = $namespace::metadata();
12✔
218
            }
219
        }
220

221
        return $providers;
12✔
222
    }
223
}
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