V.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. <?php
  2. /**
  3. * @see http://pl2.php.net/manual/en/book.var.php
  4. *
  5. * Define Your own convert function: var func_type_convert_{$type}($var);
  6. */
  7. class V {
  8. static function getValue($value, $default, $type = '') {
  9. $ret = ($value) ? $value : $default;
  10. return ('' != $type) ? V::convert($ret, $type) : $ret;
  11. }
  12. /**
  13. * Get variable from array or object - case insensitive
  14. */
  15. public static function geti($name, $default, $from, $type = '', $filterCallback = null) {
  16. $lowerFrom = array();
  17. if (!is_object($from) && !is_array($from)) throw new Exception("Bad param - from must be array or object");
  18. foreach ((array)$from as $fieldName => $value) {
  19. $lowerFrom[ strtolower($fieldName) ] = $value;
  20. }
  21. return V::get(strtolower($name), $default, $lowerFrom, $type, $filterCallback);
  22. }
  23. /**
  24. * Get variable from array or object.
  25. */
  26. public static function get($name, $default, $from, $type = '', $filterCallback = null) {
  27. if (empty($name)) return null;
  28. $ret = null;
  29. if (is_bool($name)) $name = (int)$name;
  30. if (!is_string($name) && !is_numeric($name)) {
  31. //var_dump($name);
  32. //echo'<pre>';print_r(debug_backtrace());echo'</pre>';
  33. throw new Exception("Error name is not scalar! '{$name}'");
  34. }
  35. if (is_array($from)) {
  36. if (array_key_exists($name, $from)) {
  37. $ret = $from[$name];
  38. }
  39. }
  40. else if (is_object($from)) {
  41. if (isset($from->$name)) {
  42. $ret = $from->$name;
  43. }
  44. }
  45. if (isset($ret) && $type != '') {
  46. $ret = V::convert($ret, $type);
  47. }
  48. if (!empty($filterCallback)) {
  49. if ($type == 'array' && is_array($ret) && !empty($ret)) {
  50. $ret = V::filter($ret, $filterCallback);
  51. }
  52. }
  53. $ret = (null !== $ret)? $ret : $default;
  54. return $ret;
  55. }
  56. /**
  57. * Convert variable type.
  58. * @usage: V::convert($from, 'url');
  59. */
  60. public static function convert($from, $type = 'string') {
  61. switch ($type) {
  62. case 'minOccurs':
  63. case 'maxOccurs': // The default values for minOccurs and maxOccurs are 1 - @return int or 'unbounded', default is 1
  64. if (!is_scalar($from)) return null;
  65. if (!strlen($from)) return 1;
  66. if ("unbounded" === $from) return "unbounded";
  67. return (int)$from;
  68. }
  69. $type = strtolower($type);
  70. // is_scalar($from) - return TRUE if int,float,string,bool, FALSE if array,object,resource, ...
  71. $ret = null;
  72. switch ($type) {
  73. case 'string':
  74. if (is_scalar($from)) {
  75. $ret = $from;
  76. settype($ret, $type);
  77. }
  78. return $ret;
  79. case 'word':
  80. if (is_scalar($from)) {
  81. $ret = $from;
  82. settype($ret, 'string');
  83. $ret = trim($ret);
  84. if (false !== ($pos = strpos($ret, ' '))) {
  85. $ret = substr($ret, 0, $pos);
  86. }
  87. }
  88. return $ret;
  89. case 'login':// [a-zA-Z.-_]
  90. if (is_scalar($from)) {
  91. $ret = $from;
  92. settype($ret, 'string');
  93. $ret = trim($ret);
  94. if (!preg_match("/^[a-zA-Z.-_]*$/", $ret, $matches)) {
  95. $ret = null;
  96. }
  97. }
  98. return $ret;
  99. case 'url':// [a-zA-Z0-9_-]
  100. if (is_scalar($from)) {
  101. $ret = $from;
  102. settype($ret, 'string');
  103. $ret = trim($ret);
  104. $pl_letters = array('ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż', 'Ą', 'Ć', 'Ę', 'Ł', 'Ń', 'Ó', 'Ś', 'Ź', 'Ż');
  105. $en_letters = array('a', 'c', 'e', 'l', 'n', 'o', 's', 'z', 'z', 'A', 'C', 'E', 'L', 'N', 'O', 'S', 'Z', 'Z');
  106. $ret = str_replace($pl_letters, $en_letters, $ret);
  107. $ret = preg_replace('/[^a-zA-Z0-9_-]+/', '_', $ret);
  108. }
  109. return $ret;
  110. case 'int':
  111. case 'integer':
  112. if (is_scalar($from)) {
  113. $ret = $from;
  114. settype($ret, $type);
  115. }
  116. return $ret;
  117. case 'float':
  118. case 'double':
  119. if (is_scalar($from)) {
  120. $ret = str_replace(',', '.', $from);
  121. settype($ret, $type);
  122. }
  123. return $ret;
  124. case 'price':// 0.00 - decimal(n, 2)
  125. if (is_scalar($from)) {
  126. $ret = str_replace(',', '.', $from);
  127. settype($ret, 'float');
  128. $ret = round($ret, 2);
  129. }
  130. return $ret;
  131. case 'object':
  132. case 'array':
  133. if (is_scalar($from) || is_array($from) || is_object($from)) {
  134. $ret = $from;
  135. settype($ret, $type);
  136. }
  137. return $ret;
  138. case 'int_array':
  139. if (is_scalar($from) || is_array($from) || is_object($from)) {
  140. $ret = array();
  141. $arr = $from;
  142. settype($arr, 'array');
  143. foreach ($arr as $v) {
  144. $v = V::convert($v, 'int');
  145. $ret[] = $v;
  146. }
  147. }
  148. return $ret;
  149. case 'uint_array':// unsigned int array
  150. if (is_scalar($from) || is_array($from) || is_object($from)) {
  151. $ret = array();
  152. $arr = $from;
  153. settype($arr, 'array');
  154. foreach ($arr as $v) {
  155. $v = V::convert($v, 'int');
  156. if ($v <= 0) continue;
  157. $ret[] = $v;
  158. }
  159. }
  160. return $ret;
  161. case 'float_array':// uncigned int array
  162. if (is_scalar($from) || is_array($from) || is_object($from)) {
  163. $ret = array();
  164. $arr = $from;
  165. settype($arr, 'array');
  166. foreach ($arr as $v) {
  167. $v = V::convert($v, 'float');
  168. $ret[] = $v;
  169. }
  170. }
  171. return $ret;
  172. case 'bool':
  173. case 'boolean': return (bool)$from;
  174. default:
  175. $fun = 'func_type_convert_'.$type;
  176. return (function_exists($fun)) ? $fun($from) : null;
  177. }
  178. }
  179. /**
  180. * Merge the contents of two objects/array.
  181. *
  182. * array V::extend(mixed $defaults, mixed $params);
  183. * @see http://api.jquery.com/jQuery.extend/
  184. * is_scalar($from) - return TRUE if int,float,string,bool, FALSE if array,object,resource, ...
  185. */
  186. public static function extend($defaults, $params) {
  187. $ret = array();
  188. $d = (is_array($defaults))? $defaults : (array)$defaults;
  189. $p = (is_array($params))? $params : (array)$params;
  190. foreach ($d as $k => $v) {
  191. $ret[$k] = $v;
  192. }
  193. foreach ($p as $k => $v) {
  194. if (array_key_exists($k, $ret) && (is_array($ret[$k]) || is_object($ret[$k])) && (is_array($v) || is_object($v))) {
  195. $ret[$k] = V::extend($ret[$k], $v);
  196. } else {
  197. $ret[$k] = $v;
  198. }
  199. }
  200. return $ret;
  201. }
  202. public static function json_encode_latin2($o, $force_object = false) {
  203. if ($o === '') {
  204. return '""';
  205. }
  206. else if (!$o) {
  207. return 'null';
  208. }
  209. else if (is_array($o)) {
  210. $arr = '';
  211. if ($force_object) {
  212. foreach ($o as $k => $v) {
  213. $arr[] = '"'.$k.'":'.V::json_encode_latin2($v, $force_object);
  214. }
  215. return '{'.implode(',',$arr).'}';
  216. }
  217. else {
  218. foreach ($o as $k => $v) {
  219. if (is_string($k)) $arr[] = '"'.$k.'":'.V::json_encode_latin2($v, $force_object);
  220. else $arr[] = V::json_encode_latin2($v);
  221. }
  222. return '['.implode(',',$arr).']';
  223. }
  224. }
  225. else if (is_object($o)) {
  226. $arr = '';
  227. foreach (get_object_vars($o) as $k => $v) {
  228. $arr[] = '"'.$k.'":'.V::json_encode_latin2($v, $force_object);
  229. }
  230. return '{'.implode(',',$arr).'}';
  231. }
  232. else if (is_string($o)) {
  233. return '"'.addslashes(str_replace(array("\n","\r"), array('\n',''), $o)).'"';
  234. }
  235. else if (is_numeric($o)) {
  236. return ''.$o.'';
  237. }
  238. else if (is_bool($o)) {
  239. return ''.(($o)? 'true' : 'false').'';
  240. }
  241. }
  242. static function safePrintPrettyJson($json) {
  243. if (empty($json)) return '{}';
  244. try {
  245. $decoded = json_decode($json);
  246. if (NULL === $decoded) {
  247. throw new Exception(json_last_error());
  248. }
  249. return json_encode($decoded, $options = JSON_PRETTY_PRINT);
  250. } catch (Exception $e) {
  251. DBG::log($e);
  252. return 'JSON DECODE ERROR: ' . $e->getMessage();
  253. }
  254. }
  255. public static function copy($o) {
  256. $null = null;
  257. if (!$o) {
  258. return $null;
  259. }
  260. else if (is_array($o)) {
  261. $ret = array();
  262. foreach ($o as $k => $v) {
  263. $ret[$k] = $v;
  264. }
  265. return $ret;
  266. }
  267. else if (is_object($o)) {
  268. $ret = new stdClass();
  269. foreach (get_object_vars($o) as $k => $v) {
  270. $ret->$k = $v;
  271. }
  272. return $ret;
  273. }
  274. else {
  275. $ret = $o;
  276. return $ret;
  277. }
  278. }
  279. public static function make_link($prefix = '', $params = array()) {
  280. $ret = '';
  281. if ($prefix) {
  282. $ret = $prefix;
  283. }
  284. if (!empty($params)) {
  285. $ret_arr = array();
  286. foreach ($params as $k => $v) {
  287. $ret_arr[] = $k . "=" . $v;
  288. }
  289. $ret .= "?" . implode("&", $ret_arr);
  290. }
  291. return $ret;
  292. }
  293. public static function strShort($label, $maxLength = 10, $suffix = ' ...') {
  294. if (strlen($label) > $maxLength) {
  295. $pos = strpos($label, ' - ');
  296. if ($pos > $maxLength || $pos < 5) {
  297. $label = substr($label, 0, $maxLength) . $suffix;
  298. } else {
  299. $label = substr($label, 0, $pos);
  300. }
  301. }
  302. return $label;
  303. }
  304. public static function strShortUtf8($label, $maxLength = 10, $suffix = ' ...') {
  305. if (mb_strlen($label, 'utf-8') > $maxLength) {
  306. $pos = mb_strpos($label, ' - ', 0, 'utf-8');
  307. if ($pos > $maxLength || $pos < 5) {
  308. $label = mb_substr($label, 0, $maxLength, 'utf-8') . $suffix;
  309. } else {
  310. $label = mb_substr($label, 0, $pos, 'utf-8');
  311. }
  312. }
  313. return $label;
  314. }
  315. public static function filter($array, $filterCallback) {
  316. if (!is_callable($filterCallback)) {
  317. throw new Exception("callback is not callable '" . ((is_array($filterCallback))? implode('.', $filterCallback) : $filterCallback) . "'");
  318. }
  319. return array_filter($array, $filterCallback);
  320. }
  321. public static function filterNotEmpty($value) {
  322. return !empty($value);
  323. }
  324. public static function filterNotEmptyString($value) {
  325. if ('0' === $value) return true;
  326. return !empty($value);
  327. }
  328. public static function filterInteger($value) {// An integer or string with integer value
  329. if (is_int($value)) {
  330. return true;
  331. } else if (is_string($value)) {
  332. if ((string)(int)$value === $value) {
  333. return true;
  334. }
  335. }
  336. return false;
  337. }
  338. public static function filterNegativeInteger($value) {// An integer containing only negative values (..,-2,-1)
  339. if (V::filterInteger($value)) {
  340. if (intval($value) < 0) {
  341. return true;
  342. }
  343. }
  344. return false;
  345. }
  346. public static function filterNonNegativeInteger($value) {// An integer containing only non-negative values (0,1,2,..)
  347. if (V::filterInteger($value)) {
  348. if (intval($value) >= 0) {
  349. return true;
  350. }
  351. }
  352. return false;
  353. }
  354. public static function filterNonPositiveInteger($value) {// An integer containing only non-positive values (..,-2,-1,0)
  355. if (V::filterInteger($value)) {
  356. if (intval($value) <= 0) {
  357. return true;
  358. }
  359. }
  360. return false;
  361. }
  362. public static function filterPositiveInteger($value) {// An integer containing only positive values (1,2,..)
  363. if (V::filterInteger($value)) {
  364. if (intval($value) > 0) {
  365. return true;
  366. }
  367. }
  368. return false;
  369. }
  370. public static function validate($argName, $args, $params) {
  371. //$what = V::validate('what', $args, array('type'=>'word', 'not_empty'=>true, 'max_length'=>'255', 'values'=>$when_values));
  372. $argValue = V::get($argName, null, $args);
  373. $fldLabel = V::get('fld_label', $argName, $params);
  374. if (array_key_exists('not_empty', $params) && true == $params['not_empty']) {
  375. if (!array_key_exists($argName, $args) || empty($args[$argName])) throw new Exception("Field {$fldLabel} not set.");
  376. }
  377. $params['fld_label'] = $fldLabel;
  378. return V::validateValue($argValue, $params);
  379. }
  380. public static function validateValue($value, $params) {
  381. $fldLabel = V::get('fld_label', '', $params);
  382. $maxLength = V::get('max_length', 0, $params);
  383. if ($maxLength > 0) {
  384. if (strlen($value) > $maxLength) throw new Exception("'{$fldLabel}' cannot be longer then {$maxLength}.");
  385. }
  386. $allowedValues = V::get('values', null, $params);
  387. if (is_array($allowedValues) && !empty($allowedValues)) {
  388. if (!in_array($value, $allowedValues)) throw new Exception("'{$fldLabel}' value is not allowed");
  389. }
  390. $type = V::get('type', null, $params);
  391. if ($type != null) {
  392. if ('word' == $type) {
  393. if (!is_scalar($value) || !preg_match('/^[a-zA-Z_-]*$/', $value)) throw new Exception("required type '{$type}' ({$fldLabel})");
  394. } else if ('login' == $type) {
  395. if (!is_scalar($value) || !preg_match('/^[a-zA-Z\._-]*$/', $value)) throw new Exception("required type '{$type}' ({$fldLabel})");
  396. } else {
  397. throw new Exception("Unimplemented type to validate: '{$type}'");
  398. }
  399. }
  400. if (array_key_exists('equal', $params)) {
  401. if ($value != $params['equal']) throw new Exception(V::get('error_msg_equal', "'{$fldLabel}' must be equal to '{$params['equal']}'", $params));
  402. }
  403. if (array_key_exists('equalStrict', $params)) {
  404. if ($value !== $params['equalStrict']) throw new Exception(V::get('error_msg_equalStrict', "'{$fldLabel}' must be strict equal to '{$params['equal']}'", $params));
  405. }
  406. return $value;
  407. }
  408. public static function exec($cmd, &$out, &$ret) {
  409. $out = null;
  410. $ret = null;
  411. // NOTE: SourceGuardian requires file: "${HOME}/.config/SourceGuardian/"
  412. $cmd = implode("\n", [
  413. "PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/local/bin:/opt/local/lib/mysql55/bin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin:/Users/pl/programy/bin",
  414. "export HOME='/Library/WebServer'",
  415. $cmd
  416. ]);
  417. exec($cmd, $out, $ret);
  418. return $ret;
  419. }
  420. static function shell_exec($cmd) {
  421. $out = null;
  422. $ret = null;
  423. // NOTE: SourceGuardian requires file: "${HOME}/.config/SourceGuardian/"
  424. $cmd = implode("\n", [
  425. "PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/local/bin:/opt/local/lib/mysql55/bin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin:/Users/pl/programy/bin",
  426. "export HOME='/Library/WebServer'",
  427. $cmd
  428. ]);
  429. return shell_exec($cmd);
  430. }
  431. public static function execRemote($host, $login, $password, $command, &$out, &$ret, $port = 22) {
  432. $out = null;
  433. $ret = null;
  434. $pass = $password;
  435. $pass = str_replace('!', '\!', $pass);
  436. $sshPort = (22 != $port)? "-p {$port}" : '';
  437. $cmd = '/opt/local/bin/sshpass -p ' . $pass . ' ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=99999 ' . $sshPort . ' ' . $login . '@' . $host . ' -t <<EOF
  438. declare PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/local/bin:/opt/local/lib/mysql55/bin/:/Applications/Server.app/Contents/ServerRoot/usr/sbin/
  439. '.$command.'
  440. EOF';
  441. exec($cmd, $out, $ret);
  442. return $ret;
  443. }
  444. public static function execRootRemote($host, $login, $password, $command, &$out, &$ret, $port = 22) {
  445. $out = null;
  446. $ret = null;
  447. $pass = $password;
  448. $pass = str_replace('!', '\!', $pass);
  449. $sshPort = (22 != $port)? "-p {$port}" : '';
  450. $cmd = '/opt/local/bin/sshpass -p ' . $pass . ' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=99999 ' . $sshPort . ' ' . $login . '@' . $host . ' -t <<EOF
  451. sudo -n su -
  452. declare PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/local/bin:/opt/local/lib/mysql55/bin/:/Applications/Server.app/Contents/ServerRoot/usr/sbin/
  453. '.$command.'
  454. EOF';
  455. exec($cmd, $out, $ret);
  456. return $ret;
  457. }
  458. public static function quoteBashEcho($string) {
  459. return str_replace([ '"', '$' ], [ '\"', '\$' ], $string);
  460. }
  461. public static function cloneArray($arr) {
  462. return $arr;
  463. }
  464. public static function humanFileSize($bytes) {
  465. $bytes = intval($bytes);
  466. $arBytes = array(
  467. 0 => array("UNIT" => "TB", "VALUE" => pow(1024, 4)),
  468. 1 => array("UNIT" => "GB", "VALUE" => pow(1024, 3)),
  469. 2 => array("UNIT" => "MB", "VALUE" => pow(1024, 2)),
  470. 3 => array("UNIT" => "KB", "VALUE" => 1024),
  471. 4 => array("UNIT" => "B", "VALUE" => 1)
  472. );
  473. foreach($arBytes as $arItem) {
  474. if ($bytes >= $arItem["VALUE"]) {
  475. $result = $bytes / $arItem["VALUE"];
  476. $result = str_replace(".", "," , strval(round($result, 2)))." ".$arItem["UNIT"];
  477. break;
  478. }
  479. }
  480. return $result;
  481. }
  482. public static function kwotaSlownie($kwota = 0, $waluta = "PLN") {
  483. if (!preg_match("/^[[:digit:]]*(\.[[:digit:]]+)?$/",$kwota)) throw new Exception("Błędna liczba");
  484. if (!preg_match("/^[[:digit:]]{0,48}(\.[[:digit:]]+)?$/",$kwota)) throw new Exception("Zbyt duża liczba");
  485. $waluty = array(
  486. 'PLN' => array('złoty','złotych','złote'),
  487. 'USD' => array('dolar','dolarów','dolary')
  488. );
  489. $jednosci = array('zero','jeden','dwa','trzy','cztery','pięć','sześć','siedem','osiem','dziewięć','dziesięć','jedenaście',
  490. 'dwanaście','trzynaście','czternaście','piętnaście','szesnaście','siednaście','osiemnaście','dziewiętnaście');
  491. $dziesiatki = array('','','dwadzieścia','trzydzieści','czterdzieści','pięćdziesiąt','sześćdziesiąt','siedemdziesiąt','osiemdziesiąt','dziewięćdziesiąt');
  492. $setki = array('','sto','dwieście','trzysta','czterysta','pięćset','sześćset','siedemset','osiemset','dziewięćset');
  493. if (!isset($waluty[$waluta])) $tysiace[] = array($waluta,$waluta,$waluta);
  494. else $tysiace[] = $waluty[$waluta];
  495. $tysiace[] = array('tysiąc','tysięcy','tysiące');
  496. $tysiace[] = array('milion','milionów','miliony');
  497. $tysiace[] = array('miliard','miliardów','miliardy');
  498. $tysiace[] = array('bilion','bilionów','bilony');
  499. $tysiace[] = array('biliard','biliardów','biliardy');
  500. $tysiace[] = array('trylion','trylionów','tryliony');
  501. $tysiace[] = array('tryliard','tryliardów','tryliardy');
  502. $tysiace[] = array('kwadrylion','kwadrylionów','kwadryliony');
  503. $tysiace[] = array('kwadryliard','kwadryliardów','kwaryliardy');
  504. $tysiace[] = array('kwintylion','kwintylionów','kwintyliony');
  505. $tysiace[] = array('kwintyliard','kwintyliardów','kwintyliardy');
  506. $tysiace[] = array('sekstylion','sekstylionów','sepstyliony');
  507. $tysiace[] = array('sekstyliard','sekstyliardów','sekstyliardy');
  508. $tysiace[] = array('septylion','septylionów','septyliony');
  509. $tysiace[] = array('septyliard','septyliardów','septyliardy');
  510. $kwota = (!substr_count($kwota, '.')) ? $kwota.'.00' : $kwota;
  511. list($zlote, $grosze) = explode('.', $kwota);
  512. $zlote = ltrim($zlote, '0');
  513. if ($zlote == '') $zlote = '0';
  514. if (strlen($grosze) == 1) $grosze .= "0";
  515. elseif (strlen($grosze) > 2) $grosze = round(substr($grosze, 0, 2).".".substr($grosze, 2), 0);
  516. $zlote = strrev(wordwrap(strrev($zlote), 3, '.', true));
  517. $zloteArr = explode('.', $zlote);
  518. foreach ($zloteArr as $i => $l) {
  519. $tysiac = count($zloteArr) - $i - 1;
  520. $setka = $setki[floor($l/100)];
  521. $dziesiatka = $dziesiatki[floor(($l%100)/10)];
  522. $jednosc = $dziesiatka ? $jednosci[$l%10] : $jednosci[$l%100];
  523. if ($l == 1 and ($tysiac > 0 or count($zloteArr) == 1)) $odmiana = 0;
  524. elseif (floor($l%100/10) != 1 and $l%10 >= 2 and $l%10 <= 4) $odmiana = 2;
  525. else $odmiana = 1;
  526. if ($setka) $resultArr[] = $setka;
  527. if ($dziesiatka) $resultArr[] = $dziesiatka;
  528. if ($jednosc == $jednosci[0] && $zlote != '0') $jednosc = '';
  529. if ($jednosc) $resultArr[] = $jednosc;
  530. if ($setka || $dziesiatka || $jednosc || $tysiac == 0) $resultArr[] = $tysiace[$tysiac][$odmiana];
  531. }
  532. $resultArr[] = $grosze . "/100";
  533. return implode(" ", $resultArr);
  534. }
  535. public static function nettoOdBrutto($brutto = 0, $vat = "23") {
  536. if ($vat < 0) throw new Exception("Stawka VAT nie może być liczbą ujemną!");
  537. $netto = round($brutto/(1+$vat/100),2);
  538. if (round($netto*(1+$vat/100),2) > $brutto) $netto -= 0.01;
  539. return $netto;
  540. }
  541. public static function makePick($fieldName, $default = '', $type = null) {
  542. return function ($item) use ($fieldName, $default, $type) {
  543. return V::get($fieldName, $default, $item, $type);
  544. };
  545. }
  546. public static function makeSplit($splitChar, $total) {
  547. return function ($string) use ($splitChar, $total) {
  548. return ($total) ? explode($splitChar, $string, $total) : explode($splitChar, $string);
  549. };
  550. }
  551. public static function makeJoin($joinChar) {
  552. return function ($string) use ($joinChar) {
  553. return implode($joinChar, $string);
  554. };
  555. }
  556. public static function pickSimgleValue($items, $fieldName) {
  557. return array_map(
  558. function ($row) use ($fieldName) {
  559. return V::get($fieldName, '', $row);
  560. }
  561. , $items
  562. );
  563. }
  564. public static function pickArrayValues($items, $fieldNames) {
  565. return $items;
  566. }
  567. static function addSingleQuotes($str) {
  568. return "'{$str}'";
  569. }
  570. public static function arrayToXML($array, $formatOutput = false, $root = "root") {
  571. $arrayToXML_rec = function($data, $dom, $node, $parent = null) use (&$arrayToXML_rec) {
  572. $child = $dom->createElement($node);
  573. if (!$parent) $parent = $dom;
  574. if (is_array($data)) {
  575. if ($data) {
  576. foreach ($data as $key => $value) {
  577. if ((string)$key === '@attributes') {
  578. foreach ($value as $attrName => $attrValue) {
  579. $attr = $dom->createAttribute($attrName);
  580. $attr->value = $attrValue;
  581. $child->appendChild($attr);
  582. }
  583. } else {
  584. if (is_numeric($key)) $arrayToXML_rec($value, $dom, $node, $parent);
  585. else $arrayToXML_rec($value, $dom, $key, $child);
  586. }
  587. }
  588. } else $parent->appendChild($child);
  589. } else {
  590. if ($data) {
  591. if ($data == htmlspecialchars($data)) $child->nodeValue = $data;
  592. else $child->appendChild($dom->createCDATASection($data));
  593. } else $parent->appendChild($child);
  594. }
  595. if ($child->hasChildNodes() || $child->hasAttributes()) $parent->appendChild($child);
  596. };
  597. if (!is_array($array)) throw new Exception("First argument need to be an array");
  598. $dom = new DOMDocument('1.0', 'UTF-8');
  599. $dom->preserveWhiteSpace = false;
  600. $dom->formatOutput = $formatOutput;
  601. $arrayToXML_rec($array, $dom, $root);
  602. return $dom->saveXML();
  603. }
  604. // date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6),
  605. // a: '2017-07-25 13:06:15.59124',
  606. // b: '2017-07-25 13:06:15.56161',
  607. // result: '0.02963'
  608. public static function milisecondsStringDiff($a, $b) {
  609. if (25 != strlen($a)) return "Wrong length in 1st arg";
  610. if (25 != strlen($b)) return "Wrong length in 2nd arg";
  611. $aTime = array_sum([
  612. intVal(substr($a, 11, 2)) * 100000 * 60 * 60, // hour
  613. intVal(substr($a, 14, 2)) * 100000 * 60, // min
  614. intVal(substr($a, 17, 2)) * 100000, // sec
  615. intVal(substr($a, 20, 5)), // mili sec (5 digits)
  616. ]);
  617. $bTime = array_sum([
  618. intVal(substr($b, 11, 2)) * 100000 * 60 * 60, // hour
  619. intVal(substr($b, 14, 2)) * 100000 * 60, // min
  620. intVal(substr($b, 17, 2)) * 100000, // sec
  621. intVal(substr($b, 20, 5)), // mili sec (5 digits)
  622. ]);
  623. return sprintf("%0.5f", abs($aTime - $bTime) / 100000);
  624. }
  625. public static function isNip($nip) {
  626. if (!(is_numeric($nip) && preg_match('/^[[:digit:]]{10}$/', $nip))) return false;
  627. $waga = [6, 5, 7, 2, 3, 4, 5, 6, 7];
  628. $c = 0;
  629. for ($i = 0; $i < 9; $i++) $c += $nip[$i] * $waga[$i];
  630. $c = ($c % 11) % 10;
  631. return ($nip[9] == $c);
  632. }
  633. public static function isRegon($regon) {
  634. if (!(is_numeric($regon) && preg_match('/^[[:digit:]]{9}$/', $regon))) return false;
  635. $waga = [8, 9, 2, 3, 4, 5, 6, 7];
  636. $c = 0;
  637. for ($i = 0; $i < 8; $i++) $c += $regon[$i] * $waga[$i];
  638. $c = ($c % 11) % 10;
  639. return ($regon[8] == $c);
  640. }
  641. static function stripInvalidXmlChars($value = "") {
  642. return array_reduce(str_split((string)$value), function ($ret, $char) {
  643. $charCode = ord($char);
  644. if (
  645. (0x9 === $charCode)
  646. || (0xA === $charCode)
  647. || (0xD === $charCode)
  648. || (($charCode >= 0x20) && ($charCode <= 0xD7FF))
  649. || (($charCode >= 0xE000) && ($charCode <= 0xFFFD))
  650. || (($charCode >= 0x10000) && ($charCode <= 0x10FFFF))
  651. ) {
  652. return $ret . $char;
  653. }
  654. return $ret;
  655. }, "");
  656. }
  657. static function fixUtf8ToHtmlChars($input) {
  658. $input = self::stripInvalidXmlChars($input);
  659. $input = self::fixUtf8ToHtmlChar($input, 'µ', '&micro;');
  660. $input = self::fixUtf8ToHtmlChar($input, 'φ', '&phi;');
  661. $input = self::fixUtf8ToHtmlChar($input, 'Φ', '&Phi;');
  662. $input = self::fixUtf8ToHtmlChar($input, '–', '-');
  663. //$input = $this->fixUtf8ToHtmlChar($input, '°', '&deg;');// &deg; is ok in latin2
  664. return $input;
  665. }
  666. static function fixUtf8ToHtmlChar($input, $from, $to) {
  667. if (function_exists('mb_split') && false !== ($pos = mb_strpos($input, $from, 0, 'utf-8'))) {
  668. return implode($to, mb_split($from, $input));
  669. }
  670. return $input;
  671. }
  672. static function deleteWholeDirectory($dir, $returnFiles = false, $doDelete = true) {
  673. if (!is_dir($dir)) throw new Exception("{$dir} must be a directory");
  674. $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
  675. $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
  676. if ($doDelete) {
  677. $rmdir = 'rmdir';
  678. $unlink = 'unlink';
  679. } else {
  680. $rmdir = 'is_string';
  681. $unlink = 'is_string';
  682. }
  683. if ($returnFiles) {
  684. $return = [];
  685. foreach ($files as $file) {
  686. if ($file->isDir()) $return['dirs'][$file->getRealPath()] = @$rmdir($file->getRealPath());
  687. else $return['files'][$file->getRealPath()] = @$unlink($file->getRealPath());
  688. }
  689. $return['dirs'][$dir] = @$rmdir($dir);
  690. return $return;
  691. } else {
  692. foreach ($files as $file) {
  693. if ($file->isDir()) @$rmdir($file->getRealPath());
  694. else @$unlink($file->getRealPath());
  695. }
  696. @$rmdir($dir);
  697. }
  698. }
  699. static function glob($pattern, $flags = 0) {
  700. $ret = glob($pattern, $flags);
  701. return (false === $ret) ? [] : $ret;
  702. }
  703. static function tryHandleException(callable $handler, callable $callback, array $args = []) { // try again on exception
  704. try {
  705. return call_user_func_array($callback, $args);
  706. } catch (Exception $e) {
  707. DBG::log("DBG:V->tryHandleException Exception trying to fix using handler ...");
  708. DBG::log($e);
  709. $handler($e);
  710. return call_user_func_array($callback, $args);
  711. }
  712. }
  713. // @param $callback must return bool
  714. function arrayFindFirst(array $input, callable $callback) { // @return found index or -1 if not found
  715. $idx = -1;
  716. foreach ($input as $idx => $item) {
  717. if ($callback($item)) return $idx;
  718. }
  719. return $idx;
  720. }
  721. }