1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\System;
9:
10: /**
11: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
12: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
13: * @copyright Copyright (c) 2019, Afterlogic Corp.
14: *
15: * @package Api
16: */
17: class Utils
18: {
19: /**
20: * @var array
21: */
22: public static $aSuppostedCharsets = array(
23: 'iso-8859-1', 'iso-8859-2', 'iso-8859-3', 'iso-8859-4', 'iso-8859-5', 'iso-8859-6',
24: 'iso-8859-7', 'iso-8859-8', 'iso-8859-9', 'iso-8859-10', 'iso-8859-11', 'iso-8859-12',
25: 'iso-8859-13', 'iso-8859-14', 'iso-8859-15', 'iso-8859-16',
26: 'koi8-r', 'koi8-u', 'koi8-ru',
27: 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1257', 'cp949', 'cp1133',
28: 'cp850', 'cp866', 'cp1255', 'cp1256', 'cp862', 'cp874', 'cp932', 'cp950', 'cp1258',
29: 'windows-1250', 'windows-1251', 'windows-1252', 'windows-1253', 'windows-1254', 'windows-1255',
30: 'windows-1256', 'windows-1257', 'windows-1258', 'windows-874',
31: 'macroman', 'maccentraleurope', 'maciceland', 'maccroatian', 'macromania', 'maccyrillic',
32: 'macukraine', 'macgreek', 'macturkish', 'macintosh', 'machebrew', 'macarabic',
33: 'euc-jp', 'shift_jis', 'iso-2022-jp', 'iso-2022-jp-2', 'iso-2022-jp-1',
34: 'euc-cn', 'gb2312', 'hz', 'gbk', 'gb18030', 'euc-tw', 'big5', 'big5-hkscs',
35: 'iso-2022-cn', 'iso-2022-cn-ext', 'euc-kr', 'iso-2022-kr', 'johab',
36: 'armscii-8', 'georgian-academy', 'georgian-ps', 'koi8-t',
37: 'tis-620', 'macthai', 'mulelao-1',
38: 'viscii', 'tcvn', 'hp-roman8', 'nextstep',
39: 'utf-8', 'ucs-2', 'ucs-2be', 'ucs-2le', 'ucs-4', 'ucs-4be', 'ucs-4le',
40: 'utf-16', 'utf-16be', 'utf-16le', 'utf-32', 'utf-32be', 'utf-32le', 'utf-7',
41: 'c99', 'java', 'ucs-2-internal', 'ucs-4-internal');
42:
43: /**
44: * @var string
45: */
46: public static $sTimeZone = null;
47:
48: /**
49: * @return float
50: */
51: public static function Microtime()
52: {
53: return microtime(true);
54: }
55:
56: /**
57: * @param array $aArray
58: * @param string $sKey
59: * @param mixed $mDefault
60: * @return mixed
61: */
62: public static function ArrayValue($aArray, $sKey, $mDefault)
63: {
64: return (isset($aArray[$sKey])) ? $aArray[$sKey] : $mDefault;
65: }
66:
67: /**
68: * @param array $aArray
69: * @return bool
70: */
71: public static function IsAssocArray($aArray)
72: {
73: return in_array(false, array_map('is_int', array_keys($aArray)));
74: }
75:
76: /**
77: * @param string $sValue
78: * @return string
79: */
80: public static function EncodeSpecialXmlChars($sValue)
81: {
82: return str_replace('>', '&gt;', str_replace('<', '&lt;', str_replace('&', '&amp;', $sValue)));
83: }
84:
85: /**
86: * @param string $sValue
87: * @return string
88: */
89: public static function DecodeSpecialXmlChars($sValue)
90: {
91: return str_replace('&amp;', '&', str_replace('&lt;', '<', str_replace('&gt;', '>', $sValue)));
92: }
93:
94: /**
95: * @param string $sValue
96: * @return string
97: */
98: public static function EncodeSimpleSpecialXmlChars($sValue)
99: {
100: return str_replace(']]>', '&#93;&#93;&gt;', $sValue);
101: }
102:
103: /**
104: * @param string $sValue
105: * @return string
106: */
107: public static function DecodeSimpleSpecialXmlChars($sValue)
108: {
109: return str_replace('&#93;&#93;&gt;', ']]>', $sValue);
110: }
111:
112: /**
113: * @param string $sValue
114: * @return string
115: */
116: public static function ShowCRLF($sValue)
117: {
118: return str_replace(array("\r", "\n", "\t"), array('\r', '\n', '\t'), $sValue);
119: }
120:
121: /**
122: * @param string $sPath
123: * @param string $sPrefix = null
124: * @return string
125: */
126: public static function GetFullPath($sPath, $sPrefix = null)
127: {
128: if ($sPrefix !== null && !self::IsFullPath($sPath)) {
129: $sPath = rtrim($sPrefix, '\\/') . '/' . trim($sPath, '\\/');
130: }
131:
132: if (@is_dir($sPath)) {
133: $sPath = rtrim(str_replace('\\', '/', realpath($sPath)), '/');
134: }
135:
136: return $sPath;
137: }
138:
139: /**
140: * @param string $sPpath
141: * @return bool
142: */
143: public static function IsFullPath($sPpath)
144: {
145: if (strlen($sPpath) > 0) {
146: return (($sPpath[0] == '/' || $sPpath[0] == '\\') || (strlen($sPpath) > 1 && self::IsWin() && $sPpath[1] == ':'));
147: }
148: return false;
149: }
150:
151: /**
152: * @return bool
153: */
154: public static function IsWin()
155: {
156: return (defined('PHP_OS') && 'WIN' === strtoupper(substr(PHP_OS, 0, 3)));
157: }
158:
159: /**
160: * @param array $aArray
161: * @param string $sType
162: * @return array
163: */
164: public static function SetTypeArrayValue($aArray, $sType)
165: {
166: $aResult = array();
167: foreach ($aArray as $mValue) {
168: settype($mValue, $sType);
169: $aResult[] = $mValue;
170: }
171: return $aResult;
172: }
173:
174: /**
175: * @param string $sPrefix
176: * @return string
177: */
178: public static function ClearPrefix($sPrefix)
179: {
180: $sNewPrefix = preg_replace('/[^a-z0-9_]/i', '_', $sPrefix);
181: if ($sNewPrefix !== $sPrefix) {
182: $sNewPrefix = preg_replace('/[_]+/', '_', $sNewPrefix);
183: }
184: return $sNewPrefix;
185: }
186:
187: /**
188: * @param string $sEncoding
189: * @return string
190: */
191: protected static function iconvNormalizeCharset($sEncoding)
192: {
193: $sEncoding = strtolower($sEncoding);
194: switch ($sEncoding) {
195: case 'ansi':
196: case 'ansii':
197: case 'us-ansii':
198: $sEncoding = 'iso-8859-1';
199: break;
200: case 'utf8':
201: case 'utf-8':
202: $sEncoding = 'utf-8';
203: break;
204: case 'utf7-imap':
205: case 'utf7imap':
206: case 'utf-7imap':
207: case 'utf-7-imap':
208: $sEncoding = 'utf7-imap';
209: break;
210: case 'ks-c-5601-1987':
211: case 'ks_c_5601-1987':
212: $sEncoding = 'euc-kr';
213: break;
214: case 'x-gbk':
215: $sEncoding = 'gb2312';
216: break;
217: case 'iso-8859-i':
218: case 'iso-8859-8-i':
219: $sEncoding = 'iso-8859-8';
220: break;
221: }
222:
223: return $sEncoding;
224: }
225:
226: /**
227: * @param string $sString
228: * @param string $sFromEncoding
229: * @param string $sToEncoding
230: * @return string
231: */
232: public static function ConvertEncoding($sString, $sFromEncoding, $sToEncoding)
233: {
234: $sResult = $sString;
235: $sFromEncoding = self::iconvNormalizeCharset($sFromEncoding);
236: $sToEncoding = self::iconvNormalizeCharset($sToEncoding);
237:
238: if ('' === trim($sResult) || $sFromEncoding === $sToEncoding) {
239: return $sResult;
240: }
241:
242: switch (true) {
243: default:
244: break;
245: case ($sFromEncoding === 'iso-8859-1' && $sToEncoding === 'utf-8' && function_exists('mb_convert_encoding')):
246: $sResult = mb_convert_encoding($sResult, $sToEncoding, $sFromEncoding);
247: break;
248: case ($sFromEncoding === 'utf-8' && $sToEncoding === 'iso-8859-1' && function_exists('mb_convert_encoding')):
249: $sResult = mb_convert_encoding($sResult, $sToEncoding, $sFromEncoding);
250: break;
251: case ($sFromEncoding === 'utf7-imap' && $sToEncoding === 'utf-8'):
252: $sResult = self::Utf7ModifiedToUtf8($sResult);
253: if (false === $sResult) {
254: $sResult = $sString;
255: }
256: break;
257: case ($sFromEncoding === 'utf-8' && $sToEncoding === 'utf7-imap'):
258: if (!self::IsUtf7($sResult)) {
259: $sResult = self::Utf8ToUtf7Modified($sResult);
260: }
261: if (false === $sResult) {
262: $sResult = $sString;
263: }
264: break;
265: case (in_array(strtolower($sFromEncoding), self::$aSuppostedCharsets)):
266: $sResult = @iconv($sFromEncoding, $sToEncoding . '//IGNORE', $sResult);
267: if (false === $sResult) {
268: Api::Log('iconv FALSE result ["' . $sFromEncoding . '", "' . $sToEncoding . '//IGNORE", "' . substr($sString, 0, 20) . ' / cut"]', Enums\LogLevel::Error);
269: $sResult = $sString;
270: }
271: break;
272: }
273:
274: return $sResult;
275: }
276:
277: /**
278: * @param string $sValue
279: * @return string
280: */
281: public static function UrlSafeBase64Encode($sValue)
282: {
283: return \rtrim(\strtr(\base64_encode($sValue), '+/', '-_'), '=');
284: }
285:
286: /**
287: * @param string $sValue
288: * @return string
289: */
290: public static function UrlSafeBase64Decode($sValue)
291: {
292: $sValue = \rtrim(\strtr($sValue, '-_', '+/'), '=');
293: return \MailSo\Base\Utils::Base64Decode(\str_pad($sValue, \strlen($sValue) + (\strlen($sValue) % 4), '=', STR_PAD_RIGHT));
294: }
295:
296: /**
297: * @param string $sStr
298: * @return bool
299: */
300: public static function IsUtf7($sStr)
301: {
302: $iAmp = strpos($sStr, '&');
303: return (false !== $iAmp && false !== strpos($sStr, '-', $iAmp));
304: }
305:
306: /**
307: * @param string $str
308: * @return string
309: */
310: public static function Utf7ModifiedToUtf8($str)
311: {
312: $array = array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62, 63,-1,-1,-1,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1);
313:
314: $result = '';
315: $error = false;
316: $strlen = strlen($str);
317:
318: for ($i = 0; $strlen > 0; $i++, $strlen--) {
319: $char = $str[$i];
320: if ($char == '&') {
321: $i++;
322: $strlen--;
323:
324: $char = isset($str[$i]) ? $str[$i] : null;
325: if ($char === null) {
326: break;
327: }
328:
329: if ($strlen && $char == '-') {
330: $result .= '&';
331: continue;
332: }
333:
334: $ch = 0;
335: $k = 10;
336: for (; $strlen > 0; $i++, $strlen--) {
337: $char = $str[$i];
338:
339: $b = $array[ord($char)];
340: if ((ord($char) & 0x80) || $b == -1) {
341: break;
342: }
343:
344: if ($k > 0) {
345: $ch |= $b << $k;
346: $k -= 6;
347: } else {
348: $ch |= $b >> (-$k);
349: if ($ch < 0x80) {
350: if (0x20 <= $ch && $ch < 0x7f) {
351: return $error;
352: }
353:
354: $result .= chr($ch);
355: } elseif ($ch < 0x800) {
356: $result .= chr(0xc0 | ($ch >> 6));
357: $result .= chr(0x80 | ($ch & 0x3f));
358: } else {
359: $result .= chr(0xe0 | ($ch >> 12));
360: $result .= chr(0x80 | (($ch >> 6) & 0x3f));
361: $result .= chr(0x80 | ($ch & 0x3f));
362: }
363:
364: $ch = ($b << (16 + $k)) & 0xffff;
365: $k += 10;
366: }
367: }
368:
369: if (($ch || $k < 6) ||
370: (!$strlen || $char != '-') ||
371: ($strlen > 2 && '&' === $str[$i + 1] && '-' !== $str[$i + 2])) {
372: return $error;
373: }
374: } elseif (ord($char) < 0x20 || ord($char) >= 0x7f) {
375: return $error;
376: } else {
377: $result .= $char;
378: }
379: }
380:
381: return $result;
382: }
383:
384: /**
385: * @param string $str
386: * @return string
387: */
388: public static function Utf8ToUtf7Modified($str)
389: {
390: $array = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+',',');
391:
392: $strlen = strlen($str);
393: $isB = false;
394: $i = $n = 0;
395: $return = '';
396: $error = false;
397: $ch = $b = $k = 0;
398:
399: while ($strlen) {
400: $c = ord($str[$i]);
401: if ($c < 0x80) {
402: $ch = $c;
403: $n = 0;
404: } elseif ($c < 0xc2) {
405: return $error;
406: } elseif ($c < 0xe0) {
407: $ch = $c & 0x1f;
408: $n = 1;
409: } elseif ($c < 0xf0) {
410: $ch = $c & 0x0f;
411: $n = 2;
412: } elseif ($c < 0xf8) {
413: $ch = $c & 0x07;
414: $n = 3;
415: } elseif ($c < 0xfc) {
416: $ch = $c & 0x03;
417: $n = 4;
418: } elseif ($c < 0xfe) {
419: $ch = $c & 0x01;
420: $n = 5;
421: } else {
422: return $error;
423: }
424:
425: $i++;
426: $strlen--;
427:
428: if ($n > $strlen) {
429: return $error;
430: }
431:
432: for ($j = 0; $j < $n; $j++) {
433: $o = ord($str[$i + $j]);
434: if (($o & 0xc0) != 0x80) {
435: return $error;
436: }
437:
438: $ch = ($ch << 6) | ($o & 0x3f);
439: }
440:
441: if ($n > 1 && !($ch >> ($n * 5 + 1))) {
442: return $error;
443: }
444:
445: $i += $n;
446: $strlen -= $n;
447:
448: if ($ch < 0x20 || $ch >= 0x7f) {
449: if (!$isB) {
450: $return .= '&';
451: $isB = true;
452: $b = 0;
453: $k = 10;
454: }
455:
456: if ($ch & ~0xffff) {
457: $ch = 0xfffe;
458: }
459:
460: $return .= $array[($b | $ch >> $k)];
461: $k -= 6;
462: for (; $k >= 0; $k -= 6) {
463: $return .= $array[(($ch >> $k) & 0x3f)];
464: }
465:
466: $b = ($ch << (-$k)) & 0x3f;
467: $k += 16;
468: } else {
469: if ($isB) {
470: if ($k > 10) {
471: $return .= $array[$b];
472: }
473: $return .= '-';
474: $isB = false;
475: }
476:
477: $return .= chr($ch);
478: if ('&' === chr($ch)) {
479: $return .= '-';
480: }
481: }
482: }
483:
484: if ($isB) {
485: if ($k > 10) {
486: $return .= $array[$b];
487: }
488:
489: $return .= '-';
490: }
491:
492: return $return;
493: }
494:
495: /**
496: * @param string $sValue
497: * @return string
498: */
499: public static function EncryptValue($sValue)
500: {
501: $mKey = ctype_xdigit(Api::$sEncryptionKey) ? hex2bin(Api::$sEncryptionKey) : Api::$sEncryptionKey;
502: $sEncryptedValue = \Aurora\System\Utils\Crypt::XxteaEncrypt($sValue, $mKey);
503: return @trim(self::UrlSafeBase64Encode($sEncryptedValue));
504: }
505:
506: /**
507: * @param string $sEncryptedValue
508: * @return string
509: */
510: public static function DecryptValue($sEncryptedValue)
511: {
512: $mKey = ctype_xdigit(Api::$sEncryptionKey) ? hex2bin(Api::$sEncryptionKey) : Api::$sEncryptionKey;
513: $sEncryptedValue = self::UrlSafeBase64Decode(trim($sEncryptedValue));
514: $sValue = \Aurora\System\Utils\Crypt::XxteaDecrypt($sEncryptedValue, $mKey);
515:
516: $sCryptKey = '$2y$07$' . Api::$sEncryptionKey . '$';
517:
518: if ($sValue === false) {
519: $sValue = \Aurora\System\Utils\Crypt::XxteaDecrypt($sEncryptedValue, \md5($sCryptKey));
520: }
521:
522: if ($sValue === false) {
523: $sValue = \Aurora\System\Utils\Crypt::XxteaDecrypt($sEncryptedValue, $sCryptKey);
524: }
525:
526: return $sValue;
527: }
528:
529: /**
530: * @param string $sEncryptedValue
531: * @return string
532: */
533: public static function IsEncryptedValue($sEncryptedValue)
534: {
535: $sValue = \Aurora\System\Utils::DecryptValue($sEncryptedValue);
536: return ($sValue === false || $sValue === '') ? false : true;
537: }
538:
539: /**
540: * @param string $sEmail
541: * @return string
542: */
543: public static function GetAccountNameFromEmail($sEmail)
544: {
545: $sResult = '';
546: if (!empty($sEmail)) {
547: $iPos = strpos($sEmail, '@');
548: $sResult = (false === $iPos) ? $sEmail : substr($sEmail, 0, $iPos);
549: }
550:
551: return $sResult;
552: }
553:
554: /**
555: * @param int $iSizeInBytes
556: * @return string
557: */
558: public static function GetFriendlySize($iSizeInBytes)
559: {
560: $iSizeInKB = ceil($iSizeInBytes / 1024);
561: $iSizeInMB = $iSizeInKB / 1024;
562: if ($iSizeInMB >= 100) {
563: $iSizeInKB = ceil($iSizeInMB * 10 / 10) . 'MB';
564: } elseif ($iSizeInMB > 1) {
565: $iSizeInKB = (ceil($iSizeInMB * 10) / 10) . 'MB';
566: } else {
567: $iSizeInKB = $iSizeInKB . 'KB';
568: }
569:
570: return $iSizeInKB;
571: }
572:
573: /**
574: * @param int $iSizeInBytes
575: * @return string
576: */
577: public static function GetFriendlySizeSpec($iSizeInBytes)
578: {
579: $size = ceil($iSizeInBytes / 1024);
580: $mbSize = $size / 1024;
581: return ($mbSize > 1)
582: ? (($mbSize >= 1024)
583: ? (ceil(($mbSize * 10) / 1024) / 10) . 'GB'
584: : (ceil($mbSize * 10) / 10) . 'MB')
585: : $size . 'KB';
586: }
587:
588: /**
589: * @staticvar array $aMapping
590: * @param int $iCodePage
591: * @return string
592: */
593: public static function GetCodePageName($iCodePage)
594: {
595: static $aMapping = array(
596: 0 => 'default',
597: 51936 => 'euc-cn',
598: 936 => 'gb2312',
599: 950 => 'big5',
600: 946 => 'euc-kr',
601: 50225 => 'iso-2022-kr',
602: 50220 => 'iso-2022-jp',
603: 932 => 'shift-jis',
604: 65000 => 'utf-7',
605: 65001 => 'utf-8',
606: 1250 => 'windows-1250',
607: 1251 => 'windows-1251',
608: 1252 => 'windows-1252',
609: 1253 => 'windows-1253',
610: 1254 => 'windows-1254',
611: 1255 => 'windows-1255',
612: 1256 => 'windows-1256',
613: 1257 => 'windows-1257',
614: 1258 => 'windows-1258',
615: 20866 => 'koi8-r',
616: 28591 => 'iso-8859-1',
617: 28592 => 'iso-8859-2',
618: 28593 => 'iso-8859-3',
619: 28594 => 'iso-8859-4',
620: 28595 => 'iso-8859-5',
621: 28596 => 'iso-8859-6',
622: 28597 => 'iso-8859-7',
623: 28598 => 'iso-8859-8'
624: );
625:
626: return (isset($aMapping[$iCodePage])) ? $aMapping[$iCodePage] : '';
627: }
628:
629: /**
630: * @staticvar array $aMapping
631: * @param string $sCodePageName
632: * @return int
633: */
634: public static function GetCodePageNumber($sCodePageName)
635: {
636: static $aMapping = array(
637: 'default' => 0,
638: 'euc-cn' => 51936,
639: 'gb2312' => 936,
640: 'big5' => 950,
641: 'euc-kr' => 949,
642: 'iso-2022-kr' => 50225,
643: 'iso-2022-jp' => 50220,
644: 'shift-jis' => 932,
645: 'utf-7' => 65000,
646: 'utf-8' => 65001,
647: 'windows-1250' => 1250,
648: 'windows-1251' => 1251,
649: 'windows-1252' => 1252,
650: 'windows-1253' => 1253,
651: 'windows-1254' => 1254,
652: 'windows-1255' => 1255,
653: 'windows-1256' => 1256,
654: 'windows-1257' => 1257,
655: 'windows-1258' => 1258,
656: 'koi8-r' => 20866,
657: 'iso-8859-1' => 28591,
658: 'iso-8859-2' => 28592,
659: 'iso-8859-3' => 28593,
660: 'iso-8859-4' => 28594,
661: 'iso-8859-5' => 28595,
662: 'iso-8859-6' => 28596,
663: 'iso-8859-7' => 28597,
664: 'iso-8859-8' => 28598
665: );
666:
667: return (isset($aMapping[$sCodePageName])) ? $aMapping[$sCodePageName] : 0;
668: }
669:
670: /**
671: * @param string $sDateTime
672: * @return array|bool
673: */
674: public static function DateParse($sDateTime)
675: {
676: if (function_exists('date_parse')) {
677: return date_parse($sDateTime);
678: }
679:
680: $mReturn = false;
681: $aDateTime = explode(' ', $sDateTime, 2);
682: if (count($aDateTime) == 2) {
683: $aDate = explode('-', trim($aDateTime[0]), 3);
684: $aTime = explode(':', trim($aDateTime[1]), 3);
685:
686: if (3 === count($aDate) && 3 === count($aTime)) {
687: $mReturn = array(
688: 'year' => $aDate[0],
689: 'day' => $aDate[2],
690: 'month' => $aDate[1],
691:
692: 'hour' => $aTime[0],
693: 'minute' => $aTime[1],
694: 'second' => $aTime[2]
695: );
696: }
697: }
698: return $mReturn;
699: }
700:
701: /**
702: * @param string $sTimeOffset
703: * @return int
704: */
705: public static function GetTimeOffsetFromHoursString($sTimeOffset)
706: {
707: $iResult = 0;
708: $sTimeOffset = trim($sTimeOffset);
709: if (0 < strlen($sTimeOffset)) {
710: $sSign = $sTimeOffset[0];
711: $sTimeOffset = substr($sTimeOffset, 1);
712: $nOffset = (is_numeric($sTimeOffset)) ? (int) $sTimeOffset : 0;
713:
714: $iHours = $nOffset / 100;
715: $iMinutes = $nOffset % 100;
716:
717: $iMultiplier = ('-' === $sSign) ? -1 : 1;
718:
719: $iResult += $iMultiplier * $iHours * 60 * 60;
720: $iResult += $iMultiplier * $iMinutes * 60;
721: }
722:
723: return $iResult;
724: }
725:
726: /**
727: * @param int $iDefaultTimeZone
728: * @param string $sClientTimeZone = ''
729: * @return int
730: */
731: public static function GetTimeOffset($iDefaultTimeZone, $sClientTimeZone = '')
732: {
733: if ('' !== $sClientTimeZone) {
734: try {
735: $oDateTimeZone = new \DateTimeZone($sClientTimeZone);
736: return $oDateTimeZone->getOffset(new \DateTime('now')) / 60;
737: } catch (\Exception $oE) {
738: Api::Log($sClientTimeZone);
739: Api::LogObject($oE, Enums\LogLevel::Warning);
740: }
741: }
742:
743: $iTimeOffset = 0;
744: switch ($iDefaultTimeZone) {
745: default:
746: case 0:
747: break;
748: case 1:
749: $iTimeOffset = -12 * 60;
750: break;
751: case 2:
752: $iTimeOffset = -11 * 60;
753: break;
754: case 3:
755: $iTimeOffset = -10 * 60;
756: break;
757: case 4:
758: $iTimeOffset = -9 * 60;
759: break;
760: case 5:
761: $iTimeOffset = -8 * 60;
762: break;
763: case 6:
764: case 7:
765: $iTimeOffset = -7 * 60;
766: break;
767: case 8:
768: case 9:
769: case 10:
770: case 11:
771: $iTimeOffset = -6 * 60;
772: break;
773: case 12:
774: case 13:
775: case 14:
776: $iTimeOffset = -5 * 60;
777: break;
778: case 15:
779: case 16:
780: case 17:
781: $iTimeOffset = -4 * 60;
782: break;
783: case 18:
784: $iTimeOffset = -3.5 * 60;
785: break;
786: case 19:
787: case 20:
788: case 21:
789: $iTimeOffset = -3 * 60;
790: break;
791: case 22:
792: $iTimeOffset = -2 * 60;
793: break;
794: case 23:
795: case 24:
796: $iTimeOffset = -60;
797: break;
798: case 25:
799: case 26:
800: $iTimeOffset = 0;
801: break;
802: case 27:
803: case 28:
804: case 29:
805: case 30:
806: case 31:
807: $iTimeOffset = 60;
808: break;
809: case 32:
810: case 33:
811: case 34:
812: case 35:
813: case 36:
814: case 37:
815: $iTimeOffset = 2 * 60;
816: break;
817: case 38:
818: case 39:
819: case 40:
820: $iTimeOffset = 3 * 60;
821: break;
822: case 41:
823: $iTimeOffset = 3.5 * 60;
824: break;
825: case 42:
826: case 43:
827: case 44:
828: $iTimeOffset = 4 * 60;
829: break;
830: case 45:
831: $iTimeOffset = 4.5 * 60;
832: break;
833: case 46:
834: $iTimeOffset = 5 * 60;
835: break;
836: case 47:
837: $iTimeOffset = 5.5 * 60;
838: break;
839: case 48:
840: $iTimeOffset = 5 * 60 + 45;
841: break;
842: case 49:
843: case 50:
844: case 51:
845: case 52:
846: $iTimeOffset = 6 * 60;
847: break;
848: case 53:
849: $iTimeOffset = 6.5 * 60;
850: // no break
851: case 54:
852: $iTimeOffset = 7 * 60;
853: break;
854: case 55:
855: case 56:
856: case 57:
857: case 58:
858: case 59:
859: case 60:
860: $iTimeOffset = 8 * 60;
861: break;
862: case 61:
863: case 62:
864: $iTimeOffset = 9 * 60;
865: break;
866: case 63:
867: case 64:
868: $iTimeOffset = 9.5 * 60;
869: break;
870: case 65:
871: case 66:
872: case 67:
873: case 68:
874: case 69:
875: $iTimeOffset = 10 * 60;
876: break;
877: case 70:
878: case 71:
879: $iTimeOffset = 11 * 60;
880: break;
881: case 72:
882: case 73:
883: $iTimeOffset = 12 * 60;
884: break;
885: case 74:
886: $iTimeOffset = 13 * 60;
887: break;
888: }
889:
890: return $iTimeOffset;
891: }
892:
893: /**
894: * @param int $iDefaultTimeZone
895: * @param string $sClientTimeZone = ''
896: * @return string
897: */
898: public static function GetStrTimeZone($iDefaultTimeZone, $sClientTimeZone = '')
899: {
900: if ('' !== $sClientTimeZone) {
901: return $sClientTimeZone;
902: }
903:
904: if (null !== self::$sTimeZone) {
905: return self::$sTimeZone;
906: }
907:
908: $sResult = 'Etc/GMT';
909:
910: $aTimeZones = array(
911: 'Default', #0
912: 'Pacific/Kwajalein', #1
913: 'Pacific/Midway', #2
914: 'US/Hawaii', #3
915: 'US/Alaska', #4
916: 'America/Tijuana', #5
917: 'America/Dawson_Creek', #6
918: 'America/Denver', #7
919: 'America/Belize', #8
920: 'America/Chicago', #9
921: 'America/Cancun', #10
922: 'America/Belize', #11
923: 'America/Havana', #12
924: 'America/New_York', #13
925: 'America/Bogota', #14
926: 'America/Santiago', #15
927: 'America/Caracas', #16
928: 'America/Glace_Bay', #17
929: 'America/St_Johns', #18
930: 'America/Godthab', #19
931: 'America/Argentina/Buenos_Aires', #20
932: 'America/Sao_Paulo', #21
933: 'America/Noronha', #22
934: 'Atlantic/Cape_Verde', #23
935: 'Atlantic/Azores', #24
936: 'Africa/Abidjan', #25
937: 'Europe/Dublin', #26
938: 'Europe/Amsterdam', #27
939: 'Europe/Belgrade', #28
940: 'Europe/Brussels', #29
941: 'Europe/Sarajevo', #30
942: 'Africa/Algiers', #31
943: 'Europe/Minsk', #32
944: 'Europe/Bucharest', #33
945: 'Africa/Cairo', #34
946: 'Africa/Blantyre', #35
947: 'Africa/Harare', #36
948: 'Asia/Jerusalem', #37
949: 'Asia/Baghdad', #38
950: 'Asia/Kuwait', #39
951: 'Africa/Addis_Ababa', #40
952: 'Europe/Moscow', #41
953: 'Asia/Tehran', #42
954: 'Asia/Dubai', #43
955: 'Asia/Yerevan', #44
956: 'Asia/Kabul', #45
957: 'Asia/Tashkent', #46
958: 'Asia/Kolkata', #47
959: 'Asia/Katmandu', #48
960: 'Asia/Yekaterinburg', #49
961: 'Asia/Almaty', #50
962: 'Asia/Dhaka', #51
963: 'Asia/Colombo', #52
964: 'Asia/Rangoon', #53
965: 'Asia/Bangkok', #54
966: 'Asia/Krasnoyarsk', #55
967: 'Asia/Hong_Kong', #56
968: 'Asia/Irkutsk', #57
969: 'Asia/Kuala_Lumpur', #58
970: 'Australia/Perth', #59
971: 'Asia/Taipei', #60
972: 'Asia/Tokyo', #61
973: 'Asia/Seoul', #62
974: 'Australia/Adelaide', #63
975: 'Australia/Darwin', #64
976: 'Asia/Yakutsk', #65
977: 'Australia/Brisbane', #66
978: 'Australia/Canberra', #67
979: 'Pacific/Guam', #68
980: 'Australia/Hobart', #69
981: 'Asia/Vladivostok', #70
982: 'Pacific/Noumea', #71
983: 'Asia/Magadan', #72
984: 'Asia/Anadyr', #73
985: 'Pacific/Tongatapu' #74
986: );
987:
988: $iDefaultTimeZone = isset($aTimeZones[$iDefaultTimeZone]) ? $iDefaultTimeZone : 0;
989:
990: if (0 === $iDefaultTimeZone) {
991: $iOffset = self::GetTimeOffset($iDefaultTimeZone, $sClientTimeZone) / 60 * -1;
992: $sSign = ($iOffset < 0) ? '-' : '+';
993: $sResult = 'Etc/GMT' . $sSign . abs($iOffset);
994: } else {
995: $sResult = $aTimeZones[$iDefaultTimeZone];
996: }
997:
998: self::$sTimeZone = $sResult;
999: return self::$sTimeZone;
1000: }
1001:
1002: /**
1003: * @param string $sDir
1004: */
1005: public static function RecRmdir($sDir)
1006: {
1007: if (is_dir($sDir)) {
1008: $aObjects = scandir($sDir);
1009: foreach ($aObjects as $sObject) {
1010: if ($sObject != '.' && $sObject != '..') {
1011: if (filetype($sDir . '/' . $sObject) == 'dir') {
1012: self::RecRmdir($sDir . '/' . $sObject);
1013: } else {
1014: unlink($sDir . '/' . $sObject);
1015: }
1016: }
1017: }
1018:
1019: reset($aObjects);
1020: rmdir($sDir);
1021: }
1022: }
1023:
1024: /**
1025: * @return bool
1026: */
1027: public static function IsPhp53()
1028: {
1029: return (bool) (version_compare(phpversion(), '5.3.0') > -1);
1030: }
1031:
1032: /**
1033: * @return bool
1034: */
1035: public static function HasGdSupport()
1036: {
1037: return (bool) @function_exists('imagecreatefrompng');
1038: }
1039:
1040: /**
1041: * @return bool
1042: */
1043: public static function hasSslSupport()
1044: {
1045: return (bool) @function_exists('openssl_open');
1046: }
1047:
1048: /**
1049: * @return bool
1050: */
1051: public static function IsMcryptSupported()
1052: {
1053: return (bool) @function_exists('mcrypt_encrypt');
1054: }
1055:
1056: /**
1057: * @return bool
1058: */
1059: public static function IsIconvSupported()
1060: {
1061: return (bool) @function_exists('iconv');
1062: }
1063:
1064: /**
1065: * @return bool
1066: */
1067: public static function IsGzipSupported()
1068: {
1069: return (bool)
1070: ((false !== strpos(isset($_SERVER['HTTP_ACCEPT_ENCODING'])
1071: ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '', 'gzip'))
1072: && function_exists('gzencode'));
1073: }
1074:
1075: /**
1076: * @param string $sFileName
1077: * @return string
1078: */
1079: public static function GetFileExtension($sFileName)
1080: {
1081: $iLast = strrpos($sFileName, '.');
1082: $sExtension = '';
1083: if ($iLast !== false) {
1084: $sExtension = substr($sFileName, $iLast + 1);
1085: if (strlen($sExtension) > 5) {
1086: $sExtension = '';
1087: }
1088: }
1089: return $sExtension;
1090: }
1091:
1092: public static function GetMimeContentTypes()
1093: {
1094: return array(
1095:
1096: 'eml' => 'message/rfc822',
1097: 'mime' => 'message/rfc822',
1098: 'txt' => 'text/plain',
1099: 'text' => 'text/plain',
1100: 'def' => 'text/plain',
1101: 'list' => 'text/plain',
1102: 'in' => 'text/plain',
1103: 'ini' => 'text/plain',
1104: 'log' => 'text/plain',
1105: 'sql' => 'text/plain',
1106: 'cfg' => 'text/plain',
1107: 'conf' => 'text/plain',
1108: 'rtx' => 'text/richtext',
1109: 'vcard' => 'text/vcard',
1110: 'vcf' => 'text/vcard',
1111: 'htm' => 'text/html',
1112: 'html' => 'text/html',
1113: 'csv' => 'text/csv',
1114: 'ics' => 'text/calendar',
1115: 'ifb' => 'text/calendar',
1116: 'xml' => 'text/xml',
1117: 'json' => 'application/json',
1118: 'swf' => 'application/x-shockwave-flash',
1119: 'hlp' => 'application/winhlp',
1120: 'wgt' => 'application/widget',
1121: 'chm' => 'application/vnd.ms-htmlhelp',
1122: 'p10' => 'application/pkcs10',
1123: 'p7c' => 'application/pkcs7-mime',
1124: 'p7m' => 'application/pkcs7-mime',
1125: 'p7s' => 'application/pkcs7-signature',
1126: // 'ttf' => 'application/x-ttf',
1127: 'torrent' => 'application/x-bittorrent',
1128:
1129: // scripts
1130: 'js' => 'application/javascript',
1131: 'pl' => 'text/perl',
1132: 'css' => 'text/css',
1133: 'asp' => 'text/asp',
1134: 'php' => 'application/x-httpd-php',
1135: 'php3' => 'application/x-httpd-php',
1136: 'php4' => 'application/x-httpd-php',
1137: 'php5' => 'application/x-httpd-php',
1138: 'phtml' => 'application/x-httpd-php',
1139:
1140: // images
1141: 'png' => 'image/png',
1142: 'jpg' => 'image/jpeg',
1143: 'jpeg' => 'image/jpeg',
1144: 'jpe' => 'image/jpeg',
1145: 'jfif' => 'image/jpeg',
1146: 'gif' => 'image/gif',
1147: 'bmp' => 'image/bmp',
1148: 'cgm' => 'image/cgm',
1149: 'ief' => 'image/ief',
1150: 'ico' => 'image/x-icon',
1151: 'tif' => 'image/tiff',
1152: 'tiff' => 'image/tiff',
1153: 'svg' => 'image/svg+xml',
1154: 'svgz' => 'image/svg+xml',
1155: 'djv' => 'image/vnd.djvu',
1156: 'djvu' => 'image/vnd.djvu',
1157: 'webp' => 'image/webp',
1158:
1159: // archives
1160: 'zip' => 'application/zip',
1161: '7z' => 'application/x-7z-compressed',
1162: 'rar' => 'application/x-rar-compressed',
1163: 'exe' => 'application/x-msdownload',
1164: 'dll' => 'application/x-msdownload',
1165: 'scr' => 'application/x-msdownload',
1166: 'com' => 'application/x-msdownload',
1167: 'bat' => 'application/x-msdownload',
1168: 'msi' => 'application/x-msdownload',
1169: 'cab' => 'application/vnd.ms-cab-compressed',
1170: 'gz' => 'application/x-gzip',
1171: 'tgz' => 'application/x-gzip',
1172: 'bz' => 'application/x-bzip',
1173: 'bz2' => 'application/x-bzip2',
1174: 'deb' => 'application/x-debian-package',
1175:
1176: // fonts
1177: 'psf' => 'application/x-font-linux-psf',
1178: 'otf' => 'application/x-font-otf',
1179: 'pcf' => 'application/x-font-pcf',
1180: 'snf' => 'application/x-font-snf',
1181: 'ttf' => 'application/x-font-ttf',
1182: 'ttc' => 'application/x-font-ttf',
1183:
1184: // audio
1185: 'mp3' => 'audio/mpeg',
1186: 'amr' => 'audio/amr',
1187: 'aac' => 'audio/x-aac',
1188: 'aif' => 'audio/x-aiff',
1189: 'aifc' => 'audio/x-aiff',
1190: 'aiff' => 'audio/x-aiff',
1191: 'wav' => 'audio/x-wav',
1192: 'wma' => 'audio/x-ms-wma',
1193: 'wax' => 'audio/x-ms-wax',
1194: 'midi' => 'audio/midi',
1195: 'mp4a' => 'audio/mp4',
1196: 'ogg' => 'audio/ogg',
1197: 'weba' => 'audio/webm',
1198: 'ra' => 'audio/x-pn-realaudio',
1199: 'ram' => 'audio/x-pn-realaudio',
1200: 'rmp' => 'audio/x-pn-realaudio-plugin',
1201: 'm3u' => 'audio/x-mpegurl',
1202:
1203: // video
1204: 'flv' => 'video/x-flv',
1205: 'qt' => 'video/quicktime',
1206: 'mov' => 'video/quicktime',
1207: // 'wmv' => 'video/windows-media',
1208: 'avi' => 'video/x-msvideo',
1209: 'mpg' => 'video/mpeg',
1210: 'mpeg' => 'video/mpeg',
1211: 'mpe' => 'video/mpeg',
1212: 'm1v' => 'video/mpeg',
1213: 'm2v' => 'video/mpeg',
1214: '3gp' => 'video/3gpp',
1215: '3g2' => 'video/3gpp2',
1216: 'h261' => 'video/h261',
1217: 'h263' => 'video/h263',
1218: 'h264' => 'video/h264',
1219: 'jpgv' => 'video/jpgv',
1220: 'mp4v' => 'video/mp4',
1221: 'mpg4' => 'video/mp4',
1222: 'ogv' => 'video/ogg',
1223: 'webm' => 'video/webm',
1224: 'm4v' => 'video/x-m4v',
1225: 'asf' => 'video/x-ms-asf',
1226: 'asx' => 'video/x-ms-asf',
1227: 'wm' => 'video/x-ms-wm',
1228: 'wmv' => 'video/x-ms-wmv',
1229: 'wmx' => 'video/x-ms-wmx',
1230: 'wvx' => 'video/x-ms-wvx',
1231: 'movie' => 'video/x-sgi-movie',
1232:
1233: // adobe
1234: 'pdf' => 'application/pdf',
1235: 'psd' => 'image/vnd.adobe.photoshop',
1236: 'ai' => 'application/postscript',
1237: 'eps' => 'application/postscript',
1238: 'ps' => 'application/postscript',
1239:
1240: // ms office
1241: 'doc' => 'application/msword',
1242: 'docx' => 'application/msword',
1243: 'rtf' => 'application/rtf',
1244: 'xls' => 'application/vnd.ms-excel',
1245: 'ppt' => 'application/vnd.ms-powerpoint',
1246:
1247: // open office
1248: 'odt' => 'application/vnd.oasis.opendocument.text',
1249: 'ods' => 'application/vnd.oasis.opendocument.spreadsheet'
1250:
1251: );
1252: }
1253:
1254: /**
1255: * @param string $sFileName
1256: * @return string
1257: */
1258: public static function MimeContentType($sFileName)
1259: {
1260: $sResult = 'application/octet-stream';
1261:
1262: $aMimeTypes = self::GetMimeContentTypes();
1263: $sExt = strtolower(self::GetFileExtension($sFileName));
1264: if (!empty($sExt) && isset($aMimeTypes[$sExt])) {
1265: $sResult = $aMimeTypes[$sExt];
1266: }
1267:
1268: return $sResult;
1269: }
1270:
1271: /**
1272: * @param string $sMimeContentType
1273: * @return string
1274: */
1275: public static function GetFileExtensionFromMimeContentType($sMimeContentType)
1276: {
1277: $aMimeTypes = self::GetMimeContentTypes();
1278: return array_search($sMimeContentType, $aMimeTypes);
1279: }
1280:
1281: /**
1282: * @param string $sLanguage
1283: * @return string
1284: */
1285: public static function ConvertLanguageNameToShort($sLanguage)
1286: {
1287: $aList = array(
1288: 'arabic' => 'ar',
1289: 'bulgarian' => 'bg',
1290: 'chinese-traditional' => 'zh-tw',
1291: 'chinese-simplified' => 'zh-cn',
1292: 'czech' => 'cs',
1293: 'danish' => 'da',
1294: 'dutch' => 'nl',
1295: 'english' => 'en',
1296: 'estonian' => 'et',
1297: 'finnish' => 'fi',
1298: 'french' => 'fr',
1299: 'german' => 'de',
1300: 'greek' => 'el',
1301: 'hebrew' => 'he',
1302: 'hungarian' => 'hu',
1303: 'italian' => 'it',
1304: 'japanese' => 'ja',
1305: 'korean' => 'ko',
1306: 'latvian' => 'lv',
1307: 'lithuanian' => 'lt',
1308: 'norwegian' => 'nb',
1309: 'persian' => 'fa',
1310: 'polish' => 'pl',
1311: 'portuguese-brazil' => 'pt-br',
1312: 'portuguese-portuguese' => 'pt',
1313: 'romanian' => 'ro',
1314: 'russian' => 'ru',
1315: 'serbian' => 'sr',
1316: 'slovenian' => 'sl',
1317: 'spanish' => 'es',
1318: 'swedish' => 'sv',
1319: 'thai' => 'th',
1320: 'turkish' => 'tr',
1321: 'ukrainian' => 'uk',
1322: 'vietnamese' => 'vi'
1323: );
1324:
1325: $sLanguage = strtolower($sLanguage);
1326: return isset($aList[$sLanguage]) ? $aList[$sLanguage] : 'en';
1327: }
1328:
1329: /**
1330: * @param int $iBigInt
1331: * @return int
1332: */
1333: public static function GetGoodBigInt($iBigInt)
1334: {
1335: if (null === $iBigInt || false == $iBigInt) {
1336: return 0;
1337: } elseif ($iBigInt > AU_API_PHP_INT_MAX) {
1338: return AU_API_PHP_INT_MAX;
1339: } elseif ($iBigInt < AU_API_PHP_INT_MIN) {
1340: return AU_API_PHP_INT_MIN;
1341: }
1342:
1343: return (int) $iBigInt;
1344: }
1345:
1346: /**
1347: * @param string $sUtf8String
1348: * @param int $iLength
1349: * @return string
1350: */
1351: public static function Utf8Truncate($sUtf8String, $iLength)
1352: {
1353: if (strlen($sUtf8String) <= $iLength) {
1354: return $sUtf8String;
1355: }
1356:
1357: while ($iLength >= 0) {
1358: if ((ord($sUtf8String[$iLength]) < 0x80) || (ord($sUtf8String[$iLength]) >= 0xC0)) {
1359: return substr($sUtf8String, 0, $iLength);
1360: }
1361:
1362: $iLength--;
1363: }
1364:
1365: return '';
1366: }
1367:
1368: /**
1369: * @param string $sUtf8String
1370: * @return string
1371: */
1372: public static function Utf8ToLowerCase($sUtf8String)
1373: {
1374: if (function_exists('mb_strtolower')) {
1375: return mb_strtolower($sUtf8String, 'utf-8');
1376: }
1377:
1378: $aMapping = array(
1379: "\xC3\x80" => "\xC3\xA0", "\xC3\x81" => "\xC3\xA1",
1380: "\xC3\x82" => "\xC3\xA2", "\xC3\x83" => "\xC3\xA3", "\xC3\x84" => "\xC3\xA4", "\xC3\x85" => "\xC3\xA5",
1381: "\xC3\x86" => "\xC3\xA6", "\xC3\x87" => "\xC3\xA7", "\xC3\x88" => "\xC3\xA8", "\xC3\x89" => "\xC3\xA9",
1382: "\xC3\x8A" => "\xC3\xAA", "\xC3\x8B" => "\xC3\xAB", "\xC3\x8C" => "\xC3\xAC", "\xC3\x8D" => "\xC3\xAD",
1383: "\xC3\x8E" => "\xC3\xAE", "\xC3\x8F" => "\xC3\xAF", "\xC3\x90" => "\xC3\xB0", "\xC3\x91" => "\xC3\xB1",
1384: "\xC3\x92" => "\xC3\xB2", "\xC3\x93" => "\xC3\xB3", "\xC3\x94" => "\xC3\xB4", "\xC3\x95" => "\xC3\xB5",
1385: "\xC3\x96" => "\xC3\xB6", "\xC3\x98" => "\xC3\xB8", "\xC3\x99" => "\xC3\xB9", "\xC3\x9A" => "\xC3\xBA",
1386: "\xC3\x9B" => "\xC3\xBB", "\xC3\x9C" => "\xC3\xBC", "\xC3\x9D" => "\xC3\xBD", "\xC3\x9E" => "\xC3\xBE",
1387: "\xC4\x80" => "\xC4\x81", "\xC4\x82" => "\xC4\x83", "\xC4\x84" => "\xC4\x85", "\xC4\x86" => "\xC4\x87",
1388: "\xC4\x88" => "\xC4\x89", "\xC4\x8A" => "\xC4\x8B", "\xC4\x8C" => "\xC4\x8D", "\xC4\x8E" => "\xC4\x8F",
1389: "\xC4\x90" => "\xC4\x91", "\xC4\x92" => "\xC4\x93", "\xC4\x96" => "\xC4\x97", "\xC4\x98" => "\xC4\x99",
1390: "\xC4\x9A" => "\xC4\x9B", "\xC4\x9C" => "\xC4\x9D", "\xC4\x9E" => "\xC4\x9F", "\xC4\xA0" => "\xC4\xA1",
1391: "\xC4\xA2" => "\xC4\xA3", "\xC4\xA4" => "\xC4\xA5", "\xC4\xA6" => "\xC4\xA7", "\xC4\xA8" => "\xC4\xA9",
1392: "\xC4\xAA" => "\xC4\xAB", "\xC4\xAE" => "\xC4\xAF", "\xC4\xB4" => "\xC4\xB5", "\xC4\xB6" => "\xC4\xB7",
1393: "\xC4\xB9" => "\xC4\xBA", "\xC4\xBB" => "\xC4\xBC", "\xC4\xBD" => "\xC4\xBE", "\xC5\x81" => "\xC5\x82",
1394: "\xC5\x83" => "\xC5\x84", "\xC5\x85" => "\xC5\x86", "\xC5\x87" => "\xC5\x88", "\xC5\x8A" => "\xC5\x8B",
1395: "\xC5\x8C" => "\xC5\x8D", "\xC5\x90" => "\xC5\x91", "\xC5\x94" => "\xC5\x95", "\xC5\x96" => "\xC5\x97",
1396: "\xC5\x98" => "\xC5\x99", "\xC5\x9A" => "\xC5\x9B", "\xC5\x9C" => "\xC5\x9D", "\xC5\x9E" => "\xC5\x9F",
1397: "\xC5\xA0" => "\xC5\xA1", "\xC5\xA2" => "\xC5\xA3", "\xC5\xA4" => "\xC5\xA5", "\xC5\xA6" => "\xC5\xA7",
1398: "\xC5\xA8" => "\xC5\xA9", "\xC5\xAA" => "\xC5\xAB", "\xC5\xAC" => "\xC5\xAD", "\xC5\xAE" => "\xC5\xAF",
1399: "\xC5\xB0" => "\xC5\xB1", "\xC5\xB2" => "\xC5\xB3", "\xC5\xB4" => "\xC5\xB5", "\xC5\xB6" => "\xC5\xB7",
1400: "\xC5\xB8" => "\xC3\xBF", "\xC5\xB9" => "\xC5\xBA", "\xC5\xBB" => "\xC5\xBC", "\xC5\xBD" => "\xC5\xBE",
1401: "\xC6\xA0" => "\xC6\xA1", "\xC6\xAF" => "\xC6\xB0", "\xC8\x98" => "\xC8\x99", "\xC8\x9A" => "\xC8\x9B",
1402: "\xCE\x86" => "\xCE\xAC", "\xCE\x88" => "\xCE\xAD", "\xCE\x89" => "\xCE\xAE", "\xCE\x8A" => "\xCE\xAF",
1403: "\xCE\x8C" => "\xCF\x8C", "\xCE\x8E" => "\xCF\x8D", "\xCE\x8F" => "\xCF\x8E", "\xCE\x91" => "\xCE\xB1",
1404: "\xCE\x92" => "\xCE\xB2", "\xCE\x93" => "\xCE\xB3", "\xCE\x94" => "\xCE\xB4", "\xCE\x95" => "\xCE\xB5",
1405: "\xCE\x96" => "\xCE\xB6", "\xCE\x97" => "\xCE\xB7", "\xCE\x98" => "\xCE\xB8", "\xCE\x99" => "\xCE\xB9",
1406: "\xCE\x9A" => "\xCE\xBA", "\xCE\x9B" => "\xCE\xBB", "\xCE\x9C" => "\xCE\xBC", "\xCE\x9D" => "\xCE\xBD",
1407: "\xCE\x9E" => "\xCE\xBE", "\xCE\x9F" => "\xCE\xBF", "\xCE\xA0" => "\xCF\x80", "\xCE\xA1" => "\xCF\x81",
1408: "\xCE\xA3" => "\xCF\x83", "\xCE\xA4" => "\xCF\x84", "\xCE\xA5" => "\xCF\x85", "\xCE\xA6" => "\xCF\x86",
1409: "\xCE\xA7" => "\xCF\x87", "\xCE\xA8" => "\xCF\x88", "\xCE\xA9" => "\xCF\x89", "\xCE\xAA" => "\xCF\x8A",
1410: "\xCE\xAB" => "\xCF\x8B", "\xD0\x81" => "\xD1\x91", "\xD0\x82" => "\xD1\x92", "\xD0\x83" => "\xD1\x93",
1411: "\xD0\x84" => "\xD1\x94", "\xD0\x85" => "\xD1\x95", "\xD0\x86" => "\xD1\x96", "\xD0\x87" => "\xD1\x97",
1412: "\xD0\x88" => "\xD1\x98", "\xD0\x89" => "\xD1\x99", "\xD0\x8A" => "\xD1\x9A", "\xD0\x8B" => "\xD1\x9B",
1413: "\xD0\x8C" => "\xD1\x9C", "\xD0\x8E" => "\xD1\x9E", "\xD0\x8F" => "\xD1\x9F", "\xD0\x90" => "\xD0\xB0",
1414: "\xD0\x91" => "\xD0\xB1", "\xD0\x92" => "\xD0\xB2", "\xD0\x93" => "\xD0\xB3", "\xD0\x94" => "\xD0\xB4",
1415: "\xD0\x95" => "\xD0\xB5", "\xD0\x96" => "\xD0\xB6", "\xD0\x97" => "\xD0\xB7", "\xD0\x98" => "\xD0\xB8",
1416: "\xD0\x99" => "\xD0\xB9", "\xD0\x9A" => "\xD0\xBA", "\xD0\x9B" => "\xD0\xBB", "\xD0\x9C" => "\xD0\xBC",
1417: "\xD0\x9D" => "\xD0\xBD", "\xD0\x9E" => "\xD0\xBE", "\xD0\x9F" => "\xD0\xBF", "\xD0\xA0" => "\xD1\x80",
1418: "\xD0\xA1" => "\xD1\x81", "\xD0\xA2" => "\xD1\x82", "\xD0\xA3" => "\xD1\x83", "\xD0\xA4" => "\xD1\x84",
1419: "\xD0\xA5" => "\xD1\x85", "\xD0\xA6" => "\xD1\x86", "\xD0\xA7" => "\xD1\x87", "\xD0\xA8" => "\xD1\x88",
1420: "\xD0\xA9" => "\xD1\x89", "\xD0\xAA" => "\xD1\x8A", "\xD0\xAB" => "\xD1\x8B", "\xD0\xAC" => "\xD1\x8C",
1421: "\xD0\xAD" => "\xD1\x8D", "\xD0\xAE" => "\xD1\x8E", "\xD0\xAF" => "\xD1\x8F", "\xD2\x90" => "\xD2\x91",
1422: "\xE1\xB8\x82" => "\xE1\xB8\x83", "\xE1\xB8\x8A" => "\xE1\xB8\x8B", "\xE1\xB8\x9E" => "\xE1\xB8\x9F", "\xE1\xB9\x80" => "\xE1\xB9\x81",
1423: "\xE1\xB9\x96" => "\xE1\xB9\x97", "\xE1\xB9\xA0" => "\xE1\xB9\xA1", "\xE1\xB9\xAA" => "\xE1\xB9\xAB", "\xE1\xBA\x80" => "\xE1\xBA\x81",
1424: "\xE1\xBA\x82" => "\xE1\xBA\x83", "\xE1\xBA\x84" => "\xE1\xBA\x85", "\xE1\xBB\xB2" => "\xE1\xBB\xB3"
1425: );
1426:
1427: return strtr(strtolower($sUtf8String), $aMapping);
1428: }
1429:
1430: /**
1431: * @param string $sPabUri
1432: * @return array
1433: */
1434: public static function LdapUriParse($sPabUri)
1435: {
1436: $aReturn = array(
1437: 'host' => '127.0.0.1',
1438: 'port' => 389,
1439: 'search_dn' => '',
1440: );
1441:
1442: $sPabUriLower = strtolower($sPabUri);
1443: if ('ldap://' === substr($sPabUriLower, 0, 7)) {
1444: $sPabUriLower = substr($sPabUriLower, 7);
1445: }
1446:
1447: $aPabUriLowerExplode = explode('/', $sPabUriLower, 2);
1448: $aReturn['search_dn'] = isset($aPabUriLowerExplode[1]) ? $aPabUriLowerExplode[1] : '';
1449:
1450: if (isset($aPabUriLowerExplode[0])) {
1451: $aPabUriLowerHostPortExplode = explode(':', $aPabUriLowerExplode[0], 2);
1452: $aReturn['host'] = isset($aPabUriLowerHostPortExplode[0]) ? $aPabUriLowerHostPortExplode[0] : $aReturn['host'];
1453: $aReturn['port'] = isset($aPabUriLowerHostPortExplode[1]) ? (int) $aPabUriLowerHostPortExplode[1] : $aReturn['port'];
1454: }
1455:
1456: return $aReturn;
1457: }
1458:
1459: /**
1460: * @return string
1461: */
1462: public static function RequestUri()
1463: {
1464: $sUri = '';
1465: if (isset($_SERVER['REQUEST_URI'])) {
1466: $sUri = $_SERVER['REQUEST_URI'];
1467: } else {
1468: if (isset($_SERVER['SCRIPT_NAME'])) {
1469: if (isset($_SERVER['argv'], $_SERVER['argv'][0])) {
1470: $sUri = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['argv'][0];
1471: } elseif (isset($_SERVER['QUERY_STRING'])) {
1472: $sUri = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
1473: } else {
1474: $sUri = $_SERVER['SCRIPT_NAME'];
1475: }
1476: }
1477: }
1478:
1479: $sUri = '/' . ltrim($sUri, '/');
1480: return $sUri;
1481: }
1482:
1483: public static function DirMtime($dir)
1484: {
1485: $last_modified = 0;
1486: $files = glob($dir . '/*');
1487: foreach ($files as $file) {
1488: if (is_dir($file)) {
1489: $modified = self::DirMtime($file);
1490: } else {
1491: $modified = filemtime($file);
1492: }
1493: if ($modified > $last_modified) {
1494: $last_modified = $modified;
1495: }
1496: }
1497: return $last_modified;
1498: }
1499:
1500: public static function GlobRecursive($pattern, $flags = 0)
1501: {
1502: $files = glob($pattern, $flags);
1503:
1504: $aPaternFiles = glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT);
1505:
1506: if (is_array($aPaternFiles) && is_array($files)) {
1507: foreach ($aPaternFiles as $dir) {
1508: $files = array_merge($files, self::GlobRecursive($dir . '/' . basename($pattern), $flags));
1509: }
1510: }
1511:
1512: return is_array($files) ? $files : array();
1513: }
1514:
1515: /**
1516: * @param string $sPhone
1517: * @return string
1518: */
1519: public static function ClearPhone($sPhone)
1520: {
1521: return preg_replace('/^0000000000/', '+', preg_replace(
1522: '/[^\d]+/',
1523: '',
1524: preg_replace('/^[+]/', '0000000000', trim($sPhone))
1525: ));
1526: }
1527:
1528: /**
1529: * @param string $sSearch
1530: * @return string
1531: */
1532: public static function ClearPhoneSearch($sSearch)
1533: {
1534: return preg_replace('/[\s\-()]+/', '', preg_replace('/^[+]/', '', trim($sSearch)));
1535: }
1536:
1537: /**
1538: * @param string $sSearch
1539: * @return bool
1540: */
1541: public static function IsPhoneSearch($sSearch)
1542: {
1543: return (bool) preg_match('/^[\d]{3,}$/', self::ClearPhoneSearch($sSearch));
1544: }
1545:
1546: /**
1547: * @param string $sMimeType
1548: * @param string $sFileName = ''
1549: * @return bool
1550: */
1551: public static function IsGDImageMimeTypeSuppoted($sMimeType, $sFileName = '')
1552: {
1553: $bResult = function_exists('gd_info');
1554: if ($bResult) {
1555: $bResult = false;
1556: switch (strtolower($sMimeType)) {
1557: case 'image/jpg':
1558: case 'image/jpeg':
1559: $bResult = function_exists('imagecreatefromjpeg');
1560: break;
1561: case 'image/png':
1562: $bResult = function_exists('imagecreatefrompng');
1563: break;
1564: case 'image/gif':
1565: $bResult = function_exists('imagecreatefromgif');
1566: break;
1567: }
1568: }
1569:
1570: return $bResult;
1571: }
1572:
1573: public static function GetDirectorySize($path)
1574: {
1575: $size = 0;
1576: $files = 0;
1577: $directories = 0;
1578:
1579: $handle = is_dir($path) ? opendir($path) : null;
1580: if ($handle) {
1581: while (false !== ($file = readdir($handle))) {
1582: $nextpath = $path . '/' . $file;
1583: if ($file != '.' && $file != '..' && !is_link($nextpath)) {
1584: if (is_dir($nextpath)) {
1585: $directories++;
1586: $result = self::GetDirectorySize($nextpath);
1587: $size += $result['size'];
1588: $files += $result['files'];
1589: $directories += $result['directories'];
1590: } elseif (is_file($nextpath)) {
1591: $size += filesize($nextpath);
1592: $files++;
1593: }
1594: }
1595: }
1596:
1597: if (is_resource($handle)) {
1598: closedir($handle);
1599: }
1600: }
1601:
1602: return array(
1603: 'size' => $size,
1604: 'files' => $files,
1605: 'directories' => $directories
1606: );
1607: }
1608:
1609: public static function SearchFiles($sPath, $sPattern)
1610: {
1611: $files = array();
1612:
1613: // Create recursive dir iterator which skips dot folders
1614: $oDirIterator = new \RecursiveDirectoryIterator(
1615: $sPath,
1616: \FilesystemIterator::SKIP_DOTS |
1617: \FilesystemIterator::UNIX_PATHS
1618: );
1619:
1620: $oIterators = new \RecursiveIteratorIterator(
1621: $oDirIterator,
1622: \RecursiveIteratorIterator::SELF_FIRST
1623: );
1624:
1625: if ($sPattern === "*") {
1626: $sPattern = "\w+";
1627: } else {
1628: $sPattern = preg_quote($sPattern);
1629: }
1630:
1631: foreach ($oIterators as $oIterator) {
1632: $sName = $oIterator->getFilename();
1633: $aMatches = array();
1634:
1635: $iResult = preg_match("/" . $sPattern . "/ui", $sName, $aMatches);
1636: if ($sName !== '.sabredav' && $sName !== AU_API_HELPDESK_PUBLIC_NAME && $iResult === 1) {
1637: $files[] = $oIterator->getPathname();
1638: }
1639: }
1640:
1641: return $files;
1642: }
1643:
1644: public static function GetRemoteFileInfo($sUrl)
1645: {
1646: $aResult = array(
1647: 'size' => 0,
1648: 'content-type' => '',
1649: 'code' => 0
1650: );
1651:
1652: $oCurl = \curl_init();
1653: \curl_setopt_array($oCurl, array(
1654: CURLOPT_URL => $sUrl,
1655: CURLOPT_HEADER => true,
1656: CURLOPT_SSL_VERIFYPEER => false,
1657: CURLOPT_RETURNTRANSFER => true,
1658: CURLOPT_NOBODY => true
1659: ));
1660:
1661: \curl_exec($oCurl);
1662: $aInfo = \curl_getinfo($oCurl);
1663:
1664: if ($aInfo) {
1665: $sContentType = '';
1666: $aResult['size'] = isset($aInfo['download_content_length']) ? (int) $aInfo['download_content_length'] : 0;
1667:
1668: if (isset($aInfo['content_type'])) {
1669: $aContentType = explode(';', $aInfo['content_type']);
1670: $sContentType = isset($aContentType[0]) ? $aContentType[0] : '';
1671: }
1672:
1673: $aResult['code'] = $aInfo['http_code'];
1674: $aResult['content-type'] = $sContentType;
1675: }
1676:
1677: if (\is_resource($oCurl)) {
1678: \curl_close($oCurl);
1679: }
1680:
1681: return $aResult;
1682: }
1683:
1684: /**
1685: * @param string $sUrl
1686: * @param int $iStep Default value = **1**
1687: * @return bool
1688: */
1689: public static function GetRemoteFileRealUrl($sUrl, $iStep = 1)
1690: {
1691: $oCurl = curl_init();
1692: \curl_setopt_array($oCurl, array(
1693: CURLOPT_URL => $sUrl,
1694: CURLOPT_HEADER => true,
1695: CURLOPT_SSL_VERIFYPEER => false, //problems width soundcloud
1696: CURLOPT_RETURNTRANSFER => true,
1697: CURLOPT_NOBODY => true
1698: ));
1699: curl_exec($oCurl);
1700:
1701: $aInfo = \curl_getinfo($oCurl);
1702: $iCode = \curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
1703:
1704: curl_close($oCurl);
1705:
1706: if (($iCode === 301 || $iCode === 302) && isset($aInfo['redirect_url']) && $aInfo['redirect_url'] !== '' && $iStep < 2) {
1707: return self::GetRemoteFileRealUrl($aInfo['redirect_url'], ++$iStep);
1708: }
1709:
1710: return ($iCode === 200 || $iCode === 0 || $iCode === 400) ? $sUrl : false; //final result
1711: }
1712:
1713: public static function PopulateGoogleDriveFileInfo(&$oFileInfo)
1714: {
1715: if ($oFileInfo->mimeType !== "application/vnd.google-apps.folder" && !isset($oFileInfo->downloadUrl)) {
1716: switch($oFileInfo->mimeType) {
1717: case 'application/vnd.google-apps.document':
1718: if (is_array($oFileInfo->exportLinks)) {
1719: $oFileInfo->downloadUrl = $oFileInfo->exportLinks['application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
1720: } else {
1721: $oFileInfo->downloadUrl = $oFileInfo->exportLinks->{'application/vnd.openxmlformats-officedocument.wordprocessingml.document'};
1722: }
1723: $oFileInfo->title = $oFileInfo->title . '.docx';
1724: break;
1725: case 'application/vnd.google-apps.spreadsheet':
1726: if (is_array($oFileInfo->exportLinks)) {
1727: $oFileInfo->downloadUrl = $oFileInfo->exportLinks['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
1728: } else {
1729: $oFileInfo->downloadUrl = $oFileInfo->exportLinks->{'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'};
1730: }
1731: $oFileInfo->title = $oFileInfo->title . '.xlsx';
1732: break;
1733: case 'application/vnd.google-apps.drawing':
1734: if (is_array($oFileInfo->exportLinks)) {
1735: $oFileInfo->downloadUrl = $oFileInfo->exportLinks['image/png'];
1736: } else {
1737: $oFileInfo->downloadUrl = $oFileInfo->exportLinks->{'image/png'};
1738: }
1739: $oFileInfo->title = $oFileInfo->title . '.png';
1740: break;
1741: case 'application/vnd.google-apps.presentation':
1742: if (is_array($oFileInfo->exportLinks)) {
1743: $oFileInfo->downloadUrl = $oFileInfo->exportLinks['application/vnd.openxmlformats-officedocument.presentationml.presentation'];
1744: } else {
1745: $oFileInfo->downloadUrl = $oFileInfo->exportLinks->{'application/vnd.openxmlformats-officedocument.presentationml.presentation'};
1746: }
1747: $oFileInfo->title = $oFileInfo->title . '.pptx';
1748: break;
1749: /* default:
1750: $oFileInfo->downloadUrl = $oFileInfo->exportLinks['application/pdf'];
1751: $oFileInfo->title = $oFileInfo->title . '.pdf';
1752: break;*/
1753: }
1754: /*
1755: if (!isset($oFileInfo->fileSize))
1756: {
1757: $aRemoteFileInfo = \Aurora\System\Utils::GetRemoteFileInfo($oFileInfo->downloadUrl);
1758: $oFileInfo->fileSize = $aRemoteFileInfo['size'];
1759: }
1760: *
1761: */
1762: }
1763: }
1764:
1765: public static function GetAppUrl()
1766: {
1767: $aUrlParts = parse_url($_SERVER['HTTP_REFERER']);
1768:
1769: $sProtocol = !empty($aUrlParts['scheme']) ? $aUrlParts['scheme'] : 'http';
1770: $sHost = !empty($aUrlParts['host']) ? $aUrlParts['host'] : 'localhost';
1771: $sPath = !empty($aUrlParts['path']) ? str_replace('index.php', '', $aUrlParts['path']) : '';
1772: $sPort = !empty($aUrlParts['port']) ? ':' . $aUrlParts['port'] : '';
1773:
1774: return $sProtocol . '://' . $sHost . $sPath . $sPort;
1775: }
1776:
1777: /**
1778: * @param string $sValue
1779: * @return array
1780: */
1781: public static function ExplodeIntUids($sValue)
1782: {
1783: $aValue = explode(',', (string) $sValue);
1784: $aValue = array_map('trim', $aValue);
1785: $aValue = array_map('intval', $aValue);
1786:
1787: $aValue = array_filter($aValue, function ($iValue) {
1788: return 0 < $iValue;
1789: });
1790:
1791: return $aValue;
1792: }
1793:
1794: public static function parseIniString($sIniString)
1795: {
1796: $aResult = array();
1797: foreach (explode("\n", $sIniString) as $sLine) {
1798: $aValues = explode("=", $sLine, 2);
1799: if (isset($aValues[0], $aValues[1])) {
1800: $aResult[$aValues[0]] = trim(rtrim($aValues[1], "\r"), "\"");
1801: }
1802: }
1803: return $aResult;
1804: }
1805:
1806: /**
1807: * This function converst block CSS styles to inline styles in provided HTML.
1808: *
1809: * @param string $sHtml
1810: *
1811: * @return string
1812: */
1813: public static function ConvertCssToInlineStyles($sHtml)
1814: {
1815: $sResult = '';
1816:
1817: if (is_string($sHtml)) {
1818: preg_match_all('/<html.*?>/mi', $sHtml, $matches, PREG_SET_ORDER);
1819: if ($matches) {
1820: // custom styles processing for Outlook messages
1821: $sHtml = preg_replace('/<style><!--/mi', '<style>', $sHtml);
1822: $sHtml = preg_replace('/--><\/style>/mi', '</style>', $sHtml);
1823:
1824: // custom html processing for Outlook messages that removes empty outlook paragraphs
1825: $sHtml = preg_replace('/<o:p><\/o:p>/mi', '', $sHtml);
1826:
1827: $oCssToInlineStyles = new \TijsVerkoyen\CssToInlineStyles\CssToInlineStyles();
1828: $sResult = $oCssToInlineStyles->convert($sHtml);
1829: } else {
1830: $sResult = $sHtml;
1831: }
1832: }
1833:
1834: return $sResult;
1835: }
1836:
1837: /**
1838: * @param bool $bDownload
1839: * @param string $sContentType
1840: * @param string $sFileName
1841: *
1842: * @return void
1843: */
1844: public static function OutputFileHeaders($bDownload, $sContentType, $sFileName)
1845: {
1846: if ($bDownload) {
1847: \header('Content-Type: ' . $sContentType, true);
1848: } else {
1849: $aParts = \explode('/', $sContentType, 2);
1850: if (\in_array(\strtolower($aParts[0]), array('image', 'video', 'audio')) ||
1851: \in_array(\strtolower($sContentType), array('application/pdf', 'application/x-pdf', 'text/html'))) {
1852: \header('Content-Type: ' . $sContentType, true);
1853: } elseif (\strtolower($sContentType) === 'application/octet-stream') {
1854: $sContentType = \MailSo\Base\Utils::MimeContentType($sFileName);
1855: \header('Content-Type: ' . $sContentType, true);
1856: } else {
1857: \header('Content-Type: text/plain', true);
1858: }
1859: }
1860:
1861: \header('Content-Disposition: ' . ($bDownload ? 'attachment' : 'inline') . '; ' .
1862: \trim(\MailSo\Base\Utils::EncodeHeaderUtf8AttributeValue('filename', $sFileName)), true);
1863:
1864: \header('Accept-Ranges: none', true);
1865: \header('Content-Transfer-Encoding: binary');
1866: }
1867:
1868: public static function OutputFileResource($iUserId, $sContentType, $sFileName, $rResource, $bThumbnail, $bDownload)
1869: {
1870: self::OutputFileHeaders($bDownload, $sContentType, $sFileName);
1871:
1872: if (!$bDownload && 'text/html' === $sContentType) {
1873: $sHtml = \stream_get_contents($rResource);
1874: if ($sHtml) {
1875: $sCharset = '';
1876: $aMacth = array();
1877: if (\preg_match('/charset[\s]?=[\s]?([^\s"\']+)/i', $sHtml, $aMacth) && !empty($aMacth[1])) {
1878: $sCharset = $aMacth[1];
1879: }
1880:
1881: if ('' !== $sCharset && \MailSo\Base\Enumerations\Charset::UTF_8 !== $sCharset) {
1882: $sHtml = \MailSo\Base\Utils::ConvertEncoding(
1883: $sHtml,
1884: \MailSo\Base\Utils::NormalizeCharset($sCharset, true),
1885: \MailSo\Base\Enumerations\Charset::UTF_8
1886: );
1887: }
1888:
1889: echo '<html><head></head><body>' .
1890: \MailSo\Base\HtmlUtils::ClearHtmlSimple(self::ConvertCssToInlineStyles($sHtml), true) .
1891: '</body></html>';
1892: }
1893: } else {
1894: if ($bThumbnail && !$bDownload) {
1895: Managers\Thumb::GetResource($iUserId, $rResource, $sFileName, true);
1896: } else {
1897: \MailSo\Base\Utils::FpassthruWithTimeLimitReset($rResource);
1898: }
1899: }
1900: }
1901:
1902: public static function GetClientFileResponse($sModule, $iUserId, $sFileName, $sTempName, $iSize)
1903: {
1904: $sMimeType = \MailSo\Base\Utils::MimeContentType($sFileName);
1905: $sModule = !empty($sModule) ? $sModule : 'System';
1906:
1907: $sHash = Api::EncodeKeyValues(array(
1908: 'Module' => $sModule,
1909: 'TempFile' => true,
1910: 'UserId' => $iUserId,
1911: 'Name' => $sFileName,
1912: 'TempName' => $sTempName
1913: ));
1914: $aActions = array(
1915: 'view' => array(
1916: 'url' => '?file-cache/' . $sHash . '/view'
1917: ),
1918: 'download' => array(
1919: 'url' => '?file-cache/' . $sHash
1920: )
1921: );
1922: $oSettings = & Api::GetSettings();
1923: $iThumbnailLimit = ((int) $oSettings->GetValue('ThumbnailMaxFileSizeMb', 5)) * 1024 * 1024;
1924: $bThumb = ($oSettings->GetValue('AllowThumbnail', true) &&
1925: $iSize < $iThumbnailLimit && Utils::IsGDImageMimeTypeSuppoted($sMimeType, $sFileName));
1926: return array(
1927: 'Name' => $sFileName,
1928: 'FileName' => $sFileName,
1929: 'TempName' => $sTempName,
1930: 'MimeType' => $sMimeType,
1931: 'Size' => (int) $iSize,
1932: 'Hash' => $sHash,
1933: 'Actions' => $aActions,
1934: 'ThumbnailUrl' => $bThumb ? '?file-cache/' . $sHash . '/thumb' : '',
1935: );
1936: }
1937:
1938: /**
1939: * @param string $sFileName
1940: * @param string $sContentType
1941: * @param string $sMimeIndex = ''
1942: *
1943: * @return string
1944: */
1945: public static function clearFileName($sFileName, $sContentType, $sMimeIndex = '')
1946: {
1947: $sFileName = 0 === \strlen($sFileName) ? \preg_replace('/[^a-zA-Z0-9]/', '.', (empty($sMimeIndex) ? '' : $sMimeIndex . '.') . $sContentType) : $sFileName;
1948: $sClearedFileName = \preg_replace('/[\s]+/', ' ', \preg_replace('/[\.]+/', '.', $sFileName));
1949: $sExt = \MailSo\Base\Utils::GetFileExtension($sClearedFileName);
1950:
1951: $iSize = 100;
1952: if ($iSize < \strlen($sClearedFileName) - \strlen($sExt)) {
1953: $sClearedFileName = \substr($sClearedFileName, 0, $iSize) . (empty($sExt) ? '' : '.' . $sExt);
1954: }
1955:
1956: return \MailSo\Base\Utils::ClearFileName(\MailSo\Base\Utils::Utf8Clear($sClearedFileName));
1957: }
1958:
1959: public static function getShortClassName($sClassName)
1960: {
1961: if ($mPos = \strrpos($sClassName, '\\')) {
1962: return \substr($sClassName, $mPos + 1);
1963: }
1964: return $sClassName;
1965: }
1966:
1967: public static function getSanitizedFilename($sFileName)
1968: {
1969: return preg_replace("/[\/\*\?\[^\]<>\|:]/i", "", $sFileName);
1970: }
1971:
1972: public static function getClientIp()
1973: {
1974: $ipaddress = '';
1975:
1976: // The HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR headers can be spoofed and should not be trusted for security purposes.
1977: if (isset($_SERVER['REMOTE_ADDR'])) {
1978: $ipaddress = $_SERVER['REMOTE_ADDR'];
1979: }
1980:
1981: return $ipaddress;
1982: }
1983:
1984: public static function getClientIpInsecure()
1985: {
1986: $ipaddress = '';
1987:
1988: if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1989: $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
1990: } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1991: $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
1992: } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
1993: $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
1994: } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
1995: $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
1996: } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
1997: $ipaddress = $_SERVER['HTTP_FORWARDED'];
1998: } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1999: $ipaddress = $_SERVER['REMOTE_ADDR'];
2000: }
2001:
2002: return $ipaddress;
2003: }
2004:
2005: }
2006:
2007: /**
2008: * @package Api
2009: */
2010: class Ints
2011: {
2012: /**
2013: * @return int
2014: */
2015: public static function getIntMax()
2016: {
2017: $iMax = 0x7fff;
2018: $iProbe = 0x7fffffff;
2019: while ($iMax == ($iProbe >> 16)) {
2020: $iMax = $iProbe;
2021: $iProbe = ($iProbe << 16) + 0xffff;
2022: }
2023: return $iMax;
2024: }
2025: }
2026:
2027: function fNullCallback() {}
2028:
2029: defined('AU_API_PHP_INT_MAX') || define('AU_API_PHP_INT_MAX', (int) Ints::getIntMax());
2030: defined('AU_API_PHP_INT_MIN') || define('AU_API_PHP_INT_MIN', (int) (AU_API_PHP_INT_MAX + 1));
2031: