MyFatoorahHelper   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 296
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 91
c 2
b 0
f 0
dl 0
loc 296
rs 10
wmc 28

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getMFCountries() 0 18 5
A getWeightRate() 0 19 3
A isSignatureValid() 0 19 2
A convertArabicDigitstoEnglish() 0 15 1
A getDimensionRate() 0 20 3
A getPhone() 0 35 6
A getPaymentStatusLink() 0 5 1
A getMFConfigFileContent() 0 27 5
A filterInputField() 0 6 2
1
<?php
2
3
namespace MyFatoorah\Library;
4
5
use Exception;
6
7
/**
8
 * Trait MyFatoorah is responsible for helping calling MyFatoorah API endpoints.
9
 */
10
class MyFatoorahHelper
11
{
12
13
    /**
14
     * The file name or the logger object
15
     * It is used in logging the payment/shipping events to help in debugging and monitor the process and connections.
16
     *
17
     * @var string|object
18
     */
19
    public static $loggerObj;
20
21
    /**
22
     * The function name that will be used in the debugging if $loggerObj is set as a logger object.
23
     *
24
     * @var string
25
     */
26
    public static $loggerFunc;
27
28
    //-----------------------------------------------------------------------------------------------------------------------------------------
29
30
    /**
31
     * Returns the country code and the phone after applying MyFatoorah restriction
32
     *
33
     * Matching regular expression pattern: ^(?:(\+)|(00)|(\\*)|())[0-9]{3,14}((\\#)|())$
34
     * if (!preg_match('/^(?:(\+)|(00)|(\\*)|())[0-9]{3,14}((\\#)|())$/iD', $inputString))
35
     * String length: inclusive between 0 and 11
36
     *
37
     * @param string $inputString It is the input phone number provide by the end user.
38
     *
39
     * @return array        That contains the phone code in the 1st element the the phone number the the 2nd element.
40
     *
41
     * @throws Exception    Throw exception if the input length is less than 3 chars or long than 14 chars.
42
     */
43
    public static function getPhone($inputString)
44
    {
45
46
        //remove any arabic digit
47
        $string3 = self::convertArabicDigitstoEnglish($inputString);
48
49
        //Keep Only digits
50
        $string4 = preg_replace('/[^0-9]/', '', $string3);
51
52
        //remove 00 at start
53
        if (strpos($string4, '00') === 0) {
54
            $string4 = substr($string4, 2);
55
        }
56
57
        if (!$string4) {
58
            return ['', ''];
59
        }
60
61
        //check for the allowed length
62
        $len = strlen($string4);
63
        if ($len < 3 || $len > 14) {
64
            throw new Exception('Phone Number lenght must be between 3 to 14 digits');
65
        }
66
67
        //get the phone arr
68
        if (strlen(substr($string4, 3)) > 3) {
69
            return [
70
                substr($string4, 0, 3),
71
                substr($string4, 3)
72
            ];
73
        }
74
75
        return [
76
            '',
77
            $string4
78
        ];
79
    }
80
81
    //-----------------------------------------------------------------------------------------------------------------------------------------
82
83
    /**
84
     * Converts any Arabic or Persian numbers to English digits
85
     *
86
     * @param string $inputString It is the input phone number provide by the end user.
87
     *
88
     * @return string
89
     */
90
    protected static function convertArabicDigitstoEnglish($inputString)
91
    {
92
93
        $newNumbers = range(0, 9);
94
95
        $persianDecimal = ['&#1776;', '&#1777;', '&#1778;', '&#1779;', '&#1780;', '&#1781;', '&#1782;', '&#1783;', '&#1784;', '&#1785;']; // 1. Persian HTML decimal
96
        $arabicDecimal  = ['&#1632;', '&#1633;', '&#1634;', '&#1635;', '&#1636;', '&#1637;', '&#1638;', '&#1639;', '&#1640;', '&#1641;']; // 2. Arabic HTML decimal
97
        $arabic         = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩']; // 3. Arabic Numeric
98
        $persian        = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; // 4. Persian Numeric
99
100
        $string0 = str_replace($persianDecimal, $newNumbers, $inputString);
101
        $string1 = str_replace($arabicDecimal, $newNumbers, $string0);
102
        $string2 = str_replace($arabic, $newNumbers, $string1);
103
104
        return str_replace($persian, $newNumbers, $string2);
105
    }
106
107
    //-----------------------------------------------------------------------------------------------------------------------------------------
108
109
    /**
110
     * Get the rate that will convert the given weight unit to MyFatoorah default weight unit.
111
     * Weight must be in kg, g, lbs, or oz. Default is kg.
112
     *
113
     * @param string $unit It is the weight unit used.
114
     *
115
     * @return double|int The conversion rate that will convert the given unit into the kg.
116
     *
117
     * @throws Exception Throw exception if the input unit is not support.
118
     */
119
    public static function getWeightRate($unit)
120
    {
121
122
        $lUnit = strtolower($unit);
123
124
        //kg is the default
125
        $rateUnits = [
126
            '1'         => ['kg', 'kgs', 'كج', 'كلغ', 'كيلو جرام', 'كيلو غرام'],
127
            '0.001'     => ['g', 'جرام', 'غرام', 'جم'],
128
            '0.453592'  => ['lbs', 'lb', 'رطل', 'باوند'],
129
            '0.0283495' => ['oz', 'اوقية', 'أوقية'],
130
        ];
131
132
        foreach ($rateUnits as $rate => $unitArr) {
133
            if (array_search($lUnit, $unitArr) !== false) {
134
                return (double) $rate;
135
            }
136
        }
137
        throw new Exception('Weight units must be in kg, g, lbs, or oz. Default is kg');
138
    }
139
140
    //-----------------------------------------------------------------------------------------------------------------------------------------
141
142
    /**
143
     * Get the rate that will convert the given dimension unit to MyFatoorah default dimension unit.
144
     * Dimension must be in cm, m, mm, in, or yd. Default is cm.
145
     *
146
     * @param string $unit It is the dimension unit used in width, hight, or depth.
147
     *
148
     * @return double|int   The conversion rate that will convert the given unit into the cm.
149
     *
150
     * @throws Exception        Throw exception if the input unit is not support.
151
     */
152
    public static function getDimensionRate($unit)
153
    {
154
155
        $lUnit = strtolower($unit);
156
157
        //cm is the default
158
        $rateUnits = [
159
            '1'     => ['cm', 'سم'],
160
            '100'   => ['m', 'متر', 'م'],
161
            '0.1'   => ['mm', 'مم'],
162
            '2.54'  => ['in', 'انش', 'إنش', 'بوصه', 'بوصة'],
163
            '91.44' => ['yd', 'يارده', 'ياردة'],
164
        ];
165
166
        foreach ($rateUnits as $rate => $unitArr) {
167
            if (array_search($lUnit, $unitArr) !== false) {
168
                return (double) $rate;
169
            }
170
        }
171
        throw new Exception('Dimension units must be in cm, m, mm, in, or yd. Default is cm');
172
    }
173
174
    //-----------------------------------------------------------------------------------------------------------------------------------------
175
176
    /**
177
     * Validate webhook signature function
178
     *
179
     * @param array  $dataArray webhook request array
180
     * @param string $secret    webhook secret key
181
     * @param string $signature MyFatoorah signature
182
     * @param int    $eventType MyFatoorah Event type Number (1, 2, 3 , 4)
183
     *
184
     * @return boolean
185
     */
186
    public static function isSignatureValid($dataArray, $secret, $signature, $eventType = 0)
187
    {
188
189
        if ($eventType == 2) {
190
            unset($dataArray['GatewayReference']);
191
        }
192
193
        uksort($dataArray, 'strcasecmp');
194
195
        $mapFun = function ($v, $k) {
196
            return sprintf("%s=%s", $k, $v);
197
        };
198
        $outputArr = array_map($mapFun, $dataArray, array_keys($dataArray));
199
        $output    = implode(',', $outputArr);
200
201
        // generate hash of $field string
202
        $hash = base64_encode(hash_hmac('sha256', $output, $secret, true));
203
204
        return $signature === $hash;
205
    }
206
207
    //-----------------------------------------------------------------------------------------------------------------------------------------
208
209
    /**
210
     * Get a list of MyFatoorah countries, their API URLs, and names.
211
     *
212
     * @return array of MyFatoorah data
213
     */
214
    public static function getMFCountries()
215
    {
216
217
        $cachedFile = dirname(__FILE__) . '/mf-config.json';
218
219
        if (file_exists($cachedFile)) {
220
            if ((time() - filemtime($cachedFile) > 3600)) {
221
                $countries = self::getMFConfigFileContent($cachedFile);
222
            }
223
224
            if (!empty($countries)) {
225
                return $countries;
226
            }
227
228
            $cache = file_get_contents($cachedFile);
229
            return ($cache) ? json_decode($cache, true) : [];
230
        } else {
231
            return self::getMFConfigFileContent($cachedFile);
232
        }
233
    }
234
235
    //-----------------------------------------------------------------------------------------------------------------------------------------
236
237
    /**
238
     * Cache a list of MyFatoorah countries, their API URLs, and names.
239
     *
240
     * @param string $cachedFile The file name used in caching data.
241
     *
242
     * @return array of MyFatoorah data
243
     */
244
    protected static function getMFConfigFileContent($cachedFile)
245
    {
246
247
        $curl = curl_init('https://portal.myfatoorah.com/Files/API/mf-config.json');
248
249
        $option = [
250
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
251
            CURLOPT_RETURNTRANSFER => true
252
        ];
253
        curl_setopt_array($curl, $option);
254
255
        $response  = curl_exec($curl);
256
        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
257
        curl_close($curl);
258
259
        if ($http_code == 200 && is_string($response)) {
260
            $responseText = trim($response, ''); //remove the hidden character between the single quotes
261
            file_put_contents($cachedFile, $responseText);
262
            return json_decode($responseText, true);
263
        } elseif ($http_code == 403) {
264
            touch($cachedFile);
265
            $fileContent = file_get_contents($cachedFile);
266
            if (!empty($fileContent)) {
267
                return json_decode($fileContent, true);
268
            }
269
        }
270
        return [];
271
    }
272
273
    //-----------------------------------------------------------------------------------------------------------------------------------------
274
275
    /**
276
     * Filter an input from global variables like $_GET, $_POST, $_REQUEST, $_COOKIE, $_SERVER
277
     *
278
     * @param string $name The field name the need to be filter.
279
     * @param string $type The input type to be filter (GET, POST, REQUEST, COOKIE, SERVER).
280
     *
281
     * @return string|null
282
     */
283
    public static function filterInputField($name, $type = 'GET')
284
    {
285
        if (isset($GLOBALS["_$type"][$name])) {
286
            return htmlspecialchars($GLOBALS["_$type"][$name]);
287
        }
288
        return null;
289
    }
290
291
    //-----------------------------------------------------------------------------------------------------------------------------------------
292
293
    /**
294
     * Get the payment status link
295
     *
296
     * @param string $url       The payment URL link
297
     * @param string $paymentId The payment Id
298
     *
299
     * @return string
300
     */
301
    public static function getPaymentStatusLink($url, $paymentId)
302
    {
303
        //to overcome session urls
304
        $pattern = '/MpgsAuthentication.*|ApplePayComplete.*|GooglePayComplete.*/i';
305
        return preg_replace($pattern, "Result?paymentId=$paymentId", $url);
306
    }
307
308
    //-----------------------------------------------------------------------------------------------------------------------------------------
309
}
310