PluginProbe
AliNext – WooCommerce Dropshipping Plugin for AliExpress / trunk
AliNext – WooCommerce Dropshipping Plugin for AliExpress vtrunk
ali2woo-lite / includes / functions.php

functions.php in AliNext – WooCommerce Dropshipping Plugin for AliExpress trunk, at includes/functions.php

593 lines 20.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use AliNext_Lite\AbstractController;
4 use WpOrg\Requests\Cookie\Jar;
5 use WpOrg\Requests\Requests;
6 use WpOrg\Requests\Response;
7
8 // phpcs:ignoreFile WordPress.Security.EscapeOutput.OutputNotEscaped
9 if (!function_exists('a2wl_error_handler')) {
10
11 /**
12 * @throws Exception
13 */
14 function a2wl_error_handler($errno, $errstr, $errfile, $errline)
15 {
16 if (!(error_reporting() & $errno)) {
17 return false;
18 }
19 $typestr = match ($errno) {
20 E_ERROR => 'E_ERROR',
21 E_WARNING => 'E_WARNING',
22 E_PARSE => 'E_PARSE',
23 E_NOTICE => 'E_NOTICE',
24 E_CORE_ERROR => 'E_CORE_ERROR',
25 E_CORE_WARNING => 'E_CORE_WARNING',
26 E_COMPILE_ERROR => 'E_COMPILE_ERROR',
27 E_COMPILE_WARNING => 'E_COMPILE_WARNING',
28 E_USER_ERROR => 'E_USER_ERROR',
29 E_USER_WARNING => 'E_USER_WARNING',
30 E_USER_NOTICE => 'E_USER_NOTICE',
31 E_STRICT => 'E_STRICT',
32 E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
33 E_DEPRECATED => 'E_DEPRECATED',
34 E_USER_DEPRECATED => 'E_USER_DEPRECATED',
35 default => "Unknown error[$errno]",
36 };
37
38 a2wl_error_log(wp_strip_all_tags("$typestr: " . $errstr . " in " . $errfile . " on line " . $errline));
39 if (!in_array(
40 $typestr,
41 ['E_WARNING', 'E_NOTICE', 'E_DEPRECATED', 'E_USER_DEPRECATED', 'E_USER_WARNING', 'E_USER_NOTICE']
42 )) {
43 throw new Exception(
44 "<b>$typestr</b>: $errstr in <b>$errfile</b> on line <b>$errline</b>"
45 );
46 }
47 }
48
49 }
50
51 if (!function_exists('a2wl_random_str')) {
52 function a2wl_random_str(int $length = 12, string $keyspace = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'): string {
53 if ($length < 1) {
54 throw new \RangeException("Length must be a positive integer");
55 }
56 $pieces = [];
57 $max = mb_strlen($keyspace, '8bit') - 1;
58 for ($i = 0; $i < $length; ++$i) {
59 $pieces []= $keyspace[random_int(0, $max)];
60 }
61 return implode('', $pieces);
62 }
63 }
64
65 if (!function_exists('a2wl_init_error_handler')) {
66
67 function a2wl_init_error_handler(): ?callable
68 {
69 return set_error_handler('a2wl_error_handler');
70 }
71
72 }
73
74 if (!function_exists('a2wl_remote_get')) {
75
76 function a2wl_remote_get(string $url, array $args = [])
77 {
78 $def_args = [
79 'headers' => ['Accept-Encoding' => ''],
80 'timeout' => 30,
81 'useragent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0',
82 // 'verify' => false,
83 // 'sslverify' => false,
84 // 'verifyname' => false
85 ];
86
87 foreach ($def_args as $key => $val) {
88 if (!isset($args[$key])) {
89 $args[$key] = $val;
90 }
91 }
92
93 if (isset($args['headers'])) {
94 $headers = $args['headers'];
95 unset($args['headers']);
96 }
97
98 // If we've got cookies, use and convert them to WpOrg\Requests\Cookie.
99 if (!empty($args['cookies'])) {
100 $options['cookies'] = WP_Http::normalize_cookies($args['cookies']);
101 }
102
103 // Avoid issues where mbstring.func_overload is enabled.
104 mbstring_binary_safe_encoding();
105
106 try {
107 $Response = Requests::get($url, $headers ?? [], $args);
108
109 // Convert the response into an array
110 $response = [
111 'response' => [
112 'code' => $Response->status_code,
113 ],
114 'body' => $Response->body
115 ];
116 } catch (\WpOrg\Requests\Exception $e) {
117 $response = new WP_Error('http_request_failed', $e->getMessage());
118 } catch (Throwable $e) {
119 a2wl_print_throwable($e);
120 $response = new WP_Error('php_error', 'PHP Error');
121 }
122
123 reset_mbstring_encoding();
124
125 return $response;
126 }
127
128 }
129
130 if (!function_exists('a2wl_remote_post')) {
131
132 /**
133 * @param string $url
134 * @param string|array $data
135 * @param array $args
136 * @return array|WP_Error
137 */
138 function a2wl_remote_post(string $url, $data = [], array $args = [])
139 {
140 $def_args = [
141 'headers' => ['Accept-Encoding' => ''],
142 'timeout' => 30,
143 'useragent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0',
144 // 'verify' => false,
145 // 'sslverify' => false,
146 // 'verifyname' => false
147 ];
148
149 foreach ($def_args as $key => $val) {
150 if (!isset($args[$key])) {
151 $args[$key] = $val;
152 }
153 }
154
155 if (isset($args['headers'])) {
156 $headers = $args['headers'];
157 unset($args['headers']);
158 }
159
160 // If we've got cookies, use and convert them to WpOrg\Requests\Cookie.
161 if (!empty($args['cookies'])) {
162 $options['cookies'] = WP_Http::normalize_cookies($args['cookies']);
163 }
164
165 // Avoid issues where mbstring.func_overload is enabled.
166 mbstring_binary_safe_encoding();
167
168 try {
169 $Response = Requests::post($url, $headers ?? null, $data, $args);
170
171 // Convert the response into an array
172 $response = [
173 'response' => [
174 'code' => $Response->status_code,
175 ],
176 'body' => $Response->body
177 ];
178
179 } catch (\WpOrg\Requests\Exception $e) {
180 $response = new WP_Error('http_request_failed', $e->getMessage());
181 } catch (Throwable $e) {
182 a2wl_print_throwable($e);
183 $response = new WP_Error('php_error', 'PHP Error');
184 }
185
186 reset_mbstring_encoding();
187
188 return $response;
189 }
190
191 }
192
193 // FIX for PHP >= 7
194 // https://stackoverflow.com/questions/35701730/utf8-endecode-removed-from-php7
195 // php-xml package is missing in your php installation.
196 if (!function_exists('utf8_decode')) {
197 function utf8_decode($string)
198 {
199 // utf8_decode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support)
200 $newcharstring = '';
201 $offset = 0;
202 $stringlength = strlen($string);
203 while ($offset < $stringlength) {
204 if ((ord($string[$offset]) | 0x07) == 0xF7) {
205 // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
206 $charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
207 ((ord($string[($offset + 1)]) & 0x3F) << 12) &
208 ((ord($string[($offset + 2)]) & 0x3F) << 6) &
209 (ord($string[($offset + 3)]) & 0x3F);
210 $offset += 4;
211 } elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
212 // 1110bbbb 10bbbbbb 10bbbbbb
213 $charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
214 ((ord($string[($offset + 1)]) & 0x3F) << 6) &
215 (ord($string[($offset + 2)]) & 0x3F);
216 $offset += 3;
217 } elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
218 // 110bbbbb 10bbbbbb
219 $charval = ((ord($string[($offset + 0)]) & 0x1F) << 6) &
220 (ord($string[($offset + 1)]) & 0x3F);
221 $offset += 2;
222 } elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
223 // 0bbbbbbb
224 $charval = ord($string[$offset]);
225 $offset += 1;
226 } else {
227 // error? throw some kind of warning here?
228 $charval = false;
229 $offset += 1;
230 }
231 if ($charval !== false) {
232 $newcharstring .= (($charval < 256) ? chr($charval) : '?');
233 }
234 }
235 return $newcharstring;
236 }
237 }
238
239 if (!function_exists('a2wl_set_transient')) {
240
241 function a2wl_set_transient($transient, $value, $expiration = 0, $use_cache = false, $autoload = false)
242 {
243 if (a2wl_check_defined('A2WL_SAVE_TRANSIENT_AS_OPTION')) {
244 wp_cache_delete($transient, 'options');
245 if (false === get_option($transient)) {
246 $result = add_option($transient, $value, '', $autoload);
247 } else {
248 $result = update_option($transient, $value, $autoload);
249 }
250
251 return $result;
252 }
253
254 $expiration = (int) $expiration;
255
256 /**
257 * Filters a specific transient before its value is set.
258 *
259 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
260 *
261 * @since 3.0.0
262 * @since 4.2.0 The `$expiration` parameter was added.
263 * @since 4.4.0 The `$transient` parameter was added.
264 *
265 * @param mixed $value New value of transient.
266 * @param int $expiration Time until expiration in seconds.
267 * @param string $transient Transient name.
268 */
269 $value = apply_filters("pre_set_transient_{$transient}", $value, $expiration, $transient);
270
271 /**
272 * Filters the expiration for a transient before its value is set.
273 *
274 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
275 *
276 * @since 4.4.0
277 *
278 * @param int $expiration Time until expiration in seconds. Use 0 for no expiration.
279 * @param mixed $value New value of transient.
280 * @param string $transient Transient name.
281 */
282 $expiration = apply_filters("expiration_of_transient_{$transient}", $expiration, $value, $transient);
283
284 if ($use_cache && wp_using_ext_object_cache()) {
285 $result = wp_cache_set($transient, $value, 'transient', $expiration);
286 } else {
287 $transient_timeout = '_transient_timeout_' . $transient;
288 $transient_option = '_transient_' . $transient;
289 if (false === get_option($transient_option)) {
290 if ($expiration) {
291 $autoload = false;
292 add_option($transient_timeout, time() + $expiration, '', false);
293 }
294 $result = add_option($transient_option, $value, '', $autoload);
295 } else {
296 // If expiration is requested, but the transient has no timeout option,
297 // delete, then re-create transient rather than update.
298 $update = true;
299 if ($expiration) {
300 if (false === get_option($transient_timeout)) {
301 delete_option($transient_option);
302 add_option($transient_timeout, time() + $expiration, '', false);
303 $result = add_option($transient_option, $value, '', false);
304 $update = false;
305 } else {
306 update_option($transient_timeout, time() + $expiration);
307 }
308 }
309 if ($update) {
310 $result = update_option($transient_option, $value);
311 }
312 }
313 }
314
315 if ($result) {
316
317 /**
318 * Fires after the value for a specific transient has been set.
319 *
320 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
321 *
322 * @since 3.0.0
323 * @since 3.6.0 The `$value` and `$expiration` parameters were added.
324 * @since 4.4.0 The `$transient` parameter was added.
325 *
326 * @param mixed $value Transient value.
327 * @param int $expiration Time until expiration in seconds.
328 * @param string $transient The name of the transient.
329 */
330 do_action("set_transient_{$transient}", $value, $expiration, $transient);
331
332 /**
333 * Fires after the value for a transient has been set.
334 *
335 * @since 6.8.0
336 *
337 * @param string $transient The name of the transient.
338 * @param mixed $value Transient value.
339 * @param int $expiration Time until expiration in seconds.
340 */
341 do_action('set_transient', $transient, $value, $expiration);
342 }
343
344 return $result;
345 }
346
347 }
348
349 if (!function_exists('a2wl_get_transient')) {
350
351 function a2wl_get_transient($transient, $use_cache = false)
352 {
353 if (a2wl_check_defined('A2WL_SAVE_TRANSIENT_AS_OPTION')) {
354 return get_option($transient);
355 }
356
357 /**
358 * Filters the value of an existing transient.
359 *
360 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
361 *
362 * Passing a truthy value to the filter will effectively short-circuit retrieval
363 * of the transient, returning the passed value instead.
364 *
365 * @since 2.8.0
366 * @since 4.4.0 The `$transient` parameter was added
367 *
368 * @param mixed $pre_transient The default value to return if the transient does not exist.
369 * Any value other than false will short-circuit the retrieval
370 * of the transient, and return the returned value.
371 * @param string $transient Transient name.
372 */
373 $pre = apply_filters("pre_transient_{$transient}", false, $transient);
374 if (false !== $pre) {
375 return $pre;
376 }
377
378 if ($use_cache && wp_using_ext_object_cache()) {
379 $value = wp_cache_get($transient, 'transient');
380 } else {
381 $transient_option = '_transient_' . $transient;
382 if (!wp_installing()) {
383 // If option is not in alloptions, it is not autoloaded and thus has a timeout
384 $alloptions = wp_load_alloptions();
385 if (!isset($alloptions[$transient_option])) {
386 $transient_timeout = '_transient_timeout_' . $transient;
387 $timeout = get_option($transient_timeout);
388 if (false !== $timeout && $timeout < time()) {
389 delete_option($transient_option);
390 delete_option($transient_timeout);
391 $value = false;
392 }
393 }
394 }
395
396 if (!isset($value)) {
397 $value = get_option($transient_option);
398 }
399
400 }
401
402 /**
403 * Filters an existing transient's value.
404 *
405 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
406 *
407 * @since 2.8.0
408 * @since 4.4.0 The `$transient` parameter was added
409 *
410 * @param mixed $value Value of transient.
411 * @param string $transient Transient name.
412 */
413 return apply_filters("transient_{$transient}", $value, $transient);
414 }
415
416 }
417
418 if (!function_exists('a2wl_delete_transient')) {
419
420 function a2wl_delete_transient($transient, $use_cache = false)
421 {
422 if (a2wl_check_defined('A2WL_SAVE_TRANSIENT_AS_OPTION')) {
423 return delete_option($transient);
424 }
425 /**
426 * Fires immediately before a specific transient is deleted.
427 *
428 * The dynamic portion of the hook name, `$transient`, refers to the transient name.
429 *
430 * @since 3.0.0
431 *
432 * @param string $transient Transient name.
433 */
434 do_action("delete_transient_{$transient}", $transient);
435
436 if ($use_cache && wp_using_ext_object_cache()) {
437 $result = wp_cache_delete($transient, 'transient');
438 } else {
439 $option_timeout = '_transient_timeout_' . $transient;
440 $option = '_transient_' . $transient;
441 $result = delete_option($option);
442 if ($result) {
443 delete_option($option_timeout);
444 }
445
446 }
447
448 if ($result) {
449
450 /**
451 * Fires after a transient is deleted.
452 *
453 * @since 3.0.0
454 *
455 * @param string $transient Deleted transient name.
456 */
457 do_action('deleted_transient', $transient);
458 }
459
460 return $result;
461 }
462
463 }
464
465 if (!function_exists('a2wl_generate_call_trace')) {
466
467 function a2wl_generate_call_trace()
468 {
469 $e = new Exception();
470 $trace = array_reverse(explode("\n", $e->getTraceAsString()));
471 array_shift($trace); // remove {main}
472 array_pop($trace); // remove call to this method
473 $length = count($trace);
474 $result = array();
475 for ($i = 0; $i < $length; $i++) {
476 $result[] = ($i + 1) . ')' . substr($trace[$i], strpos($trace[$i], ' ')); // replace '#someNum' with '$i)', set the right ordering
477 }
478 return "\t" . implode("\n\t", $result);
479 }
480 }
481
482 if (!function_exists('a2wl_check_defined')) {
483 function a2wl_check_defined($name)
484 {
485 return apply_filters('a2wl_check_defined_filter', (defined($name) && constant($name)), $name);
486 }
487 }
488
489 if (!function_exists('a2wl_image_url')) {
490 function a2wl_image_url(string $image_url): string
491 {
492 if (a2wl_check_defined('A2WL_USE_CDN')) {
493 $image_url = base64_encode($image_url);
494
495 $image_url = A2WL()->plugin_url() . '/includes/cdn.php?url=' . $image_url .
496 '&_sign=' . a2wl_sign_request(array('url' => $image_url));
497 }
498
499 return $image_url;
500 }
501 }
502
503 if (!function_exists('a2wl_error_log')) {
504 function a2wl_error_log($message)
505 {
506 AliNext_Lite\Logs::getInstance()->write($message);
507 error_log($message);
508 }
509 }
510
511 if (!function_exists('a2wl_info_log')) {
512 function a2wl_info_log($message)
513 {
514 AliNext_Lite\Logs::getInstance()->write($message);
515 }
516 }
517
518 if (!function_exists('a2wl_print_throwable')) {
519 function a2wl_print_throwable(Throwable $throwable): void
520 {
521 a2wl_error_log(
522 'PHP Error: ' . $throwable->getMessage() . ', Error code: ' . $throwable->getCode() . ' in ' . $throwable->getFile() . ':' .
523 $throwable->getLine() . PHP_EOL . 'Stack trace:' . PHP_EOL . $throwable->getTraceAsString()
524 );
525 }
526 }
527
528 if (!function_exists('a2wl_gen_pk')) {
529 function a2wl_gen_pk($length = 32)
530 {
531 try {
532 $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
533 $len = strlen($chars);
534 $val = '';
535 for ($i = 0; $i < $length; $i++) {
536 $val .= $chars[wp_rand(0, $len - 1)];
537 }
538
539 if (!file_exists(WP_CONTENT_DIR . '/uploads/ali2woo/')) {
540 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir
541 mkdir(WP_CONTENT_DIR . '/uploads/ali2woo/');
542 }
543 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
544 file_put_contents(WP_CONTENT_DIR . '/uploads/ali2woo/pk.php', '<?php function a2wl_plugin_key(){return "' . $val . '";}');
545 } catch (Exception $e) {
546 a2wl_print_throwable($e);
547 }
548 }
549 }
550
551 if (!function_exists('a2wl_get_pk')) {
552 function a2wl_get_pk()
553 {
554 if (file_exists(WP_CONTENT_DIR . '/uploads/ali2woo/pk.php')) {
555 require_once WP_CONTENT_DIR . '/uploads/ali2woo/pk.php';
556 return a2wl_plugin_key();
557 }
558 return "";
559 }
560 }
561
562 if (!function_exists('a2wl_sign_request')) {
563 function a2wl_sign_request($data, $pk = false)
564 {
565 $pk = $pk ? $pk : a2wl_get_pk();
566 unset($data['_sign']);
567 ksort($data);
568 $val = "";
569 foreach ($data as $k => $v) {
570 $val .= $k . $v;
571 }
572 return md5($_SERVER['HTTP_HOST'] . $val . $pk);
573 }
574 }
575
576 if (!function_exists('a2wl_verify_request')) {
577 function a2wl_verify_request($sign, $data, $pk = false)
578 {
579 return $sign === a2wl_sign_request($data, $pk);
580 }
581 }
582
583 if (!function_exists('a2wl_json_decode')) {
584 function a2wl_json_decode($json, $assoc = true, $depth = 512, $options = 2)
585 {
586 if (function_exists('mb_convert_encoding')) {
587 $json = mb_convert_encoding($json, 'UTF-8', 'UTF-8');
588 }
589
590 return json_decode($json, $assoc, $depth, $options);
591 }
592 }
593