1: <?php
2: 3: 4: 5: 6: 7: 8:
9:
10: namespace SmartFactory;
11:
12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
23: function is_associative(array &$array): bool
24: {
25: if (!is_array($array) || empty($array)) {
26: return false;
27: }
28:
29: $keys = array_keys($array);
30:
31: return array_keys($keys) !== $keys;
32: }
33:
34: 35: 36: 37: 38: 39: 40: 41:
42: function is_web(): bool
43: {
44: return http_response_code() !== false;
45: }
46:
47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63:
64: function common_prefix(string $s1, string $s2, $max = 1000): string
65: {
66: $prefix = "";
67:
68: $l1 = strlen($s1);
69: $l2 = strlen($s2);
70:
71: for ($i = 0; $i < $max; $i++) {
72: if ($i >= $l1 || $i >= $l2) {
73: break;
74: }
75:
76: if ($s1[$i] != $s2[$i]) {
77: break;
78: }
79:
80: $prefix .= $s1[$i];
81: }
82:
83: return $prefix;
84: }
85:
86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105:
106: function json_to_array(string &$json, array &$array): void
107: {
108: $result = json_decode($json, true);
109: if ($result === null) {
110: throw new \Exception(json_last_error_msg());
111: }
112:
113: if (empty($array)) {
114: $array = [];
115: }
116:
117: $array = array_merge($array, $result);
118: }
119:
120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134:
135: function array_to_json(array &$array): string
136: {
137: return json_encode($array, JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE);
138: }
139:
140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158:
159: function array_to_dom(&$node, &$array): void
160: {
161: $xmldoc = $node->ownerDocument;
162:
163: $node->setAttribute("array", 1);
164:
165: foreach ($array as $key => &$val) {
166: $child = $xmldoc->createElement("item");
167: $child->setAttribute("name", $key);
168:
169: if (is_array($val)) {
170: array_to_dom($child, $val);
171: } else {
172: $txtnode = $xmldoc->createTextNode($val);
173: $child->appendChild($txtnode);
174: }
175:
176: $node->appendChild($child);
177: }
178: }
179:
180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198:
199: function dom_to_array(\DOMNode &$node, array &$array): void
200: {
201: if (!$node->hasChildNodes()) {
202: return;
203: }
204:
205: foreach ($node->childNodes as $child) {
206: if ($child->nodeType == XML_TEXT_NODE) {
207: continue;
208: }
209:
210: $name = $child->nodeName;
211: if ($child->nodeName == "item") {
212: $name = $child->getAttribute("name");
213: }
214:
215:
216:
217: if ($child->hasChildNodes() && $child->childNodes->length == 1 && $child->childNodes->item(0)->nodeType == XML_TEXT_NODE) {
218: $array[$name] = $child->childNodes->item(0)->nodeValue;
219: continue;
220: }
221:
222:
223:
224: if ($child->hasChildNodes() || $child->getAttribute("array") == "1") {
225: if (!isset($array[$name])) {
226: $array[$name] = array();
227: }
228: dom_to_array($child, $array[$name]);
229: continue;
230: }
231:
232: $array[$name] = $child->nodeValue;
233: }
234: }
235:
236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246:
247: function string_empty(?string $text): bool
248: {
249: if ($text === null) return true;
250:
251: if ($text === "") return true;
252:
253: return false;
254: }
255:
256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269:
270: function escape_html(?string $text): ?string
271: {
272: if (empty($text)) {
273: return $text;
274: }
275:
276: return htmlspecialchars($text, ENT_QUOTES);
277: }
278:
279: 280: 281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292:
293:
294: function escape_html_array(array &$array): void
295: {
296: foreach ($array as &$val) {
297: if (is_array($val)) {
298: escape_html_array($val);
299: } else {
300: $val = htmlspecialchars($val, ENT_QUOTES);
301: }
302: }
303: }
304:
305: 306: 307: 308: 309: 310: 311: 312: 313: 314: 315: 316: 317:
318: function escape_js(string $text): string
319: {
320: $text = str_replace("\\", "\\\\", $text);
321: $text = str_replace("\n", "\\n", $text);
322: $text = str_replace("\r", "\\r", $text);
323:
324: $text = str_replace("/", "\\/", $text);
325: $text = str_replace("'", "\\'", $text);
326: $text = str_replace("\"", "\\\"", $text);
327:
328: return $text;
329: }
330:
331: 332: 333: 334: 335: 336: 337: 338: 339: 340: 341:
342: function get_cookie(string $name): string
343: {
344: return empty($_COOKIE[$name]) ? "" : $_COOKIE[$name];
345: }
346:
347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357:
358: function get_header(string $name): string {
359: static $headers;
360:
361: if(empty($headers)) {
362: $tmp = getallheaders();
363: foreach($tmp as $header => $value) {
364: $headers[strtolower($header)] = $value;
365: }
366: }
367:
368: if(empty($headers[strtolower($name)])) return "";
369:
370: return $headers[strtolower($name)];
371: }
372:
373: 374: 375: 376: 377: 378: 379: 380: 381: 382: 383: 384: 385: 386: 387: 388: 389: 390: 391: 392:
393: function set_cookie(string $name, string $value = "", int $expires = 0, array $params = []): bool
394: {
395: if (version_compare(phpversion(), "7.3") >= 0) {
396: $params["expires"] = $expires;
397: return setcookie($name, $value, $params);
398: }
399:
400: $path = "";
401: if (!empty($params["path"])) {
402: $path = $params["path"];
403: }
404: if (!empty($params["samesite"])) {
405: $path .= "/; samesite=" . $params["samesite"];
406: }
407: return setcookie($name, $value, $expires, $path);
408: }
409:
410: 411: 412: 413: 414: 415: 416: 417: 418: 419: 420: 421: 422: 423:
424: function preg_p_escape(string $pattern): string
425: {
426: return preg_replace("/[\\\\\\[\\]\\+\\?\\-\\^\\$\\(\\)\\/\\.\\|\\{\\}\\|]/", "\\\\$0", $pattern);
427: }
428:
429: 430: 431: 432: 433: 434: 435: 436: 437: 438: 439: 440: 441: 442:
443: function preg_r_escape(string $pattern): string
444: {
445: return preg_replace("/[\\\\\\$]/", "\\\\$0", $pattern);
446: }
447:
448: 449: 450: 451: 452: 453: 454: 455: 456: 457: 458: 459: 460: 461: 462: 463: 464:
465: function timestamp(string $time_string, string $format): int|string|null
466: {
467: if (empty($time_string)) {
468: return null;
469: }
470:
471: $err_status = "error";
472:
473: $pattern = preg_replace(array("/Y/", "/m/", "/d/", "/H/", "/i/", "/s/"), array("([0-9]{4})", "([0-9]{1,2})", "([0-9]{1,2})", "([0-9]{1,2})", "([0-9]{1,2})", "([0-9]{1,2})"), preg_quote($format));
474:
475: $units = array();
476:
477: if (!preg_match("/" . $pattern . "/", $time_string, $units)) {
478: return $err_status;
479: }
480:
481: array_shift($units);
482:
483:
484:
485: $order = preg_replace("/[^YmdHis]/", "", $format);
486:
487: $date_part = "";
488: $pos_Y = strpos($order, "Y");
489: $pos_m = strpos($order, "m");
490: $pos_d = strpos($order, "d");
491: if (!($pos_Y === false || $pos_m === false || $pos_d === false)) {
492: if (!checkdate($units[$pos_m], $units[$pos_d], $units[$pos_Y])) {
493: return $err_status;
494: }
495:
496: $date_part = $units[$pos_Y] . "-" . $units[$pos_m] . "-" . $units[$pos_d];
497: }
498:
499: $time_part = "";
500: $pos_H = strpos($order, "H");
501: $pos_i = strpos($order, "i");
502: $pos_s = strpos($order, "s");
503: if (!($pos_H === false || $pos_i === false)) {
504: if (!is_numeric($units[$pos_H]) || $units[$pos_H] < 0 || $units[$pos_H] > 23) {
505: return $err_status;
506: }
507: if (!is_numeric($units[$pos_i]) || $units[$pos_i] < 0 || $units[$pos_i] > 59) {
508: return $err_status;
509: }
510:
511: $time_part = $units[$pos_H] . ":" . $units[$pos_i];
512:
513: if (!($pos_s === false)) {
514: if (!is_numeric($units[$pos_s]) || $units[$pos_s] < 0 || $units[$pos_s] > 59) {
515: return $err_status;
516: }
517: $time_part .= ":" . $units[$pos_s];
518: }
519: }
520:
521: return strtotime(trim($date_part . " " . $time_part));
522: }
523:
524: 525: 526: 527: 528: 529: 530: 531: 532: 533: 534: 535: 536: 537: 538: 539: 540: 541: 542: 543: 544: 545:
546: function format_number(string $number, int $decimals = 0, string $dec_point = ".", string $thousand_sep = ","): ?string
547: {
548: if ($number === null || $number === "") {
549: return $number;
550: }
551:
552: return number_format($number, $decimals, $dec_point, $thousand_sep);
553: }
554:
555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574:
575: function string_to_number(string $str, string $dec_point = ".", string $thousand_sep = ","): float|string|null
576: {
577: if ($str === "" || $str === null) {
578: return $str;
579: }
580:
581: $str = str_replace($thousand_sep, "", $str);
582: $str = str_replace($dec_point, ".", $str);
583: $number = floatval($str);
584:
585: return $number;
586: }
587:
588: 589: 590: 591: 592: 593: 594: 595: 596: 597: 598: 599: 600: 601: 602: 603:
604: function aes_256_encrypt(string $data, string $password_key): string
605: {
606:
607: $salt = openssl_random_pseudo_bytes(16);
608:
609: $salted = '';
610: $dx = '';
611:
612: while (strlen($salted) < 48) {
613: $dx = hash('sha256', $dx . $password_key . $salt, true);
614: $salted .= $dx;
615: }
616:
617: $key = substr($salted, 0, 32);
618: $iv = substr($salted, 32, 16);
619:
620: $encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $iv);
621: return base64_encode($salt . $encrypted_data);
622: }
623:
624: 625: 626: 627: 628: 629: 630: 631: 632: 633: 634: 635: 636: 637: 638: 639:
640: function aes_256_decrypt(string $edata, string $password_key): string
641: {
642: $data = base64_decode($edata);
643: $salt = substr($data, 0, 16);
644: $ct = substr($data, 16);
645:
646: $rounds = 3;
647: $data00 = $password_key . $salt;
648: $hash = array();
649: $hash[0] = hash('sha256', $data00, true);
650: $result = $hash[0];
651:
652: for ($i = 1; $i < $rounds; $i++) {
653: $hash[$i] = hash('sha256', $hash[$i - 1] . $data00, true);
654: $result .= $hash[$i];
655: }
656:
657: $key = substr($result, 0, 32);
658: $iv = substr($result, 32, 16);
659:
660: return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv);
661: }