$value) { $lowerFrom[ strtolower($fieldName) ] = $value; } return V::get(strtolower($name), $default, $lowerFrom, $type, $filterCallback); } /** * Get variable from array or object. */ public static function get($name, $default, $from, $type = '', $filterCallback = null) { if (empty($name)) return null; $ret = null; if (is_bool($name)) $name = (int)$name; if (!is_string($name) && !is_numeric($name)) { //var_dump($name); //echo'
';print_r(debug_backtrace());echo'
'; throw new Exception("Error name is not scalar! '{$name}'"); } if (is_array($from)) { if (array_key_exists($name, $from)) { $ret = $from[$name]; } } else if (is_object($from)) { if (isset($from->$name)) { $ret = $from->$name; } } if (isset($ret) && $type != '') { $ret = V::convert($ret, $type); } if (!empty($filterCallback)) { if ($type == 'array' && is_array($ret) && !empty($ret)) { $ret = V::filter($ret, $filterCallback); } } $ret = (null !== $ret)? $ret : $default; return $ret; } /** * Convert variable type. * @usage: V::convert($from, 'url'); */ public static function convert($from, $type = 'string') { switch ($type) { case 'minOccurs': case 'maxOccurs': // The default values for minOccurs and maxOccurs are 1 - @return int or 'unbounded', default is 1 if (!is_scalar($from)) return null; if (!strlen($from)) return 1; if ("unbounded" === $from) return "unbounded"; return (int)$from; } $type = strtolower($type); // is_scalar($from) - return TRUE if int,float,string,bool, FALSE if array,object,resource, ... $ret = null; switch ($type) { case 'string': if (is_scalar($from)) { $ret = $from; settype($ret, $type); } return $ret; case 'word': if (is_scalar($from)) { $ret = $from; settype($ret, 'string'); $ret = trim($ret); if (false !== ($pos = strpos($ret, ' '))) { $ret = substr($ret, 0, $pos); } } return $ret; case 'login':// [a-zA-Z.-_] if (is_scalar($from)) { $ret = $from; settype($ret, 'string'); $ret = trim($ret); if (!preg_match("/^[a-zA-Z.-_]*$/", $ret, $matches)) { $ret = null; } } return $ret; case 'url':// [a-zA-Z0-9_-] if (is_scalar($from)) { $ret = $from; settype($ret, 'string'); $ret = trim($ret); $pl_letters = array('ą', 'ć', 'ę', 'ł', 'ń', 'ó', 'ś', 'ź', 'ż', 'Ą', 'Ć', 'Ę', 'Ł', 'Ń', 'Ó', 'Ś', 'Ź', 'Ż'); $en_letters = array('a', 'c', 'e', 'l', 'n', 'o', 's', 'z', 'z', 'A', 'C', 'E', 'L', 'N', 'O', 'S', 'Z', 'Z'); $ret = str_replace($pl_letters, $en_letters, $ret); $ret = preg_replace('/[^a-zA-Z0-9_-]+/', '_', $ret); } return $ret; case 'int': case 'integer': if (is_scalar($from)) { $ret = $from; settype($ret, $type); } return $ret; case 'float': case 'double': if (is_scalar($from)) { $ret = str_replace(',', '.', $from); settype($ret, $type); } return $ret; case 'price':// 0.00 - decimal(n, 2) if (is_scalar($from)) { $ret = str_replace(',', '.', $from); settype($ret, 'float'); $ret = round($ret, 2); } return $ret; case 'object': case 'array': if (is_scalar($from) || is_array($from) || is_object($from)) { $ret = $from; settype($ret, $type); } return $ret; case 'int_array': if (is_scalar($from) || is_array($from) || is_object($from)) { $ret = array(); $arr = $from; settype($arr, 'array'); foreach ($arr as $v) { $v = V::convert($v, 'int'); $ret[] = $v; } } return $ret; case 'uint_array':// unsigned int array if (is_scalar($from) || is_array($from) || is_object($from)) { $ret = array(); $arr = $from; settype($arr, 'array'); foreach ($arr as $v) { $v = V::convert($v, 'int'); if ($v <= 0) continue; $ret[] = $v; } } return $ret; case 'float_array':// uncigned int array if (is_scalar($from) || is_array($from) || is_object($from)) { $ret = array(); $arr = $from; settype($arr, 'array'); foreach ($arr as $v) { $v = V::convert($v, 'float'); $ret[] = $v; } } return $ret; case 'bool': case 'boolean': return (bool)$from; default: $fun = 'func_type_convert_'.$type; return (function_exists($fun)) ? $fun($from) : null; } } /** * Merge the contents of two objects/array. * * array V::extend(mixed $defaults, mixed $params); * @see http://api.jquery.com/jQuery.extend/ * is_scalar($from) - return TRUE if int,float,string,bool, FALSE if array,object,resource, ... */ public static function extend($defaults, $params) { $ret = array(); $d = (is_array($defaults))? $defaults : (array)$defaults; $p = (is_array($params))? $params : (array)$params; foreach ($d as $k => $v) { $ret[$k] = $v; } foreach ($p as $k => $v) { if (array_key_exists($k, $ret) && (is_array($ret[$k]) || is_object($ret[$k])) && (is_array($v) || is_object($v))) { $ret[$k] = V::extend($ret[$k], $v); } else { $ret[$k] = $v; } } return $ret; } public static function json_encode_latin2($o, $force_object = false) { if ($o === '') { return '""'; } else if (!$o) { return 'null'; } else if (is_array($o)) { $arr = ''; if ($force_object) { foreach ($o as $k => $v) { $arr[] = '"'.$k.'":'.V::json_encode_latin2($v, $force_object); } return '{'.implode(',',$arr).'}'; } else { foreach ($o as $k => $v) { if (is_string($k)) $arr[] = '"'.$k.'":'.V::json_encode_latin2($v, $force_object); else $arr[] = V::json_encode_latin2($v); } return '['.implode(',',$arr).']'; } } else if (is_object($o)) { $arr = ''; foreach (get_object_vars($o) as $k => $v) { $arr[] = '"'.$k.'":'.V::json_encode_latin2($v, $force_object); } return '{'.implode(',',$arr).'}'; } else if (is_string($o)) { return '"'.addslashes(str_replace(array("\n","\r"), array('\n',''), $o)).'"'; } else if (is_numeric($o)) { return ''.$o.''; } else if (is_bool($o)) { return ''.(($o)? 'true' : 'false').''; } } static function safePrintPrettyJson($json) { if (empty($json)) return '{}'; try { $decoded = json_decode($json); if (NULL === $decoded) { throw new Exception(json_last_error()); } return json_encode($decoded, $options = JSON_PRETTY_PRINT); } catch (Exception $e) { DBG::log($e); return 'JSON DECODE ERROR: ' . $e->getMessage(); } } public static function copy($o) { $null = null; if (!$o) { return $null; } else if (is_array($o)) { $ret = array(); foreach ($o as $k => $v) { $ret[$k] = $v; } return $ret; } else if (is_object($o)) { $ret = new stdClass(); foreach (get_object_vars($o) as $k => $v) { $ret->$k = $v; } return $ret; } else { $ret = $o; return $ret; } } public static function make_link($prefix = '', $params = array()) { $ret = ''; if ($prefix) { $ret = $prefix; } if (!empty($params)) { $ret_arr = array(); foreach ($params as $k => $v) { $ret_arr[] = $k . "=" . $v; } $ret .= "?" . implode("&", $ret_arr); } return $ret; } public static function strShort($label, $maxLength = 10, $suffix = ' ...') { if (strlen($label) > $maxLength) { $pos = strpos($label, ' - '); if ($pos > $maxLength || $pos < 5) { $label = substr($label, 0, $maxLength) . $suffix; } else { $label = substr($label, 0, $pos); } } return $label; } public static function strShortUtf8($label, $maxLength = 10, $suffix = ' ...') { if (mb_strlen($label, 'utf-8') > $maxLength) { $pos = mb_strpos($label, ' - ', 0, 'utf-8'); if ($pos > $maxLength || $pos < 5) { $label = mb_substr($label, 0, $maxLength, 'utf-8') . $suffix; } else { $label = mb_substr($label, 0, $pos, 'utf-8'); } } return $label; } public static function filter($array, $filterCallback) { if (!is_callable($filterCallback)) { throw new Exception("callback is not callable '" . ((is_array($filterCallback))? implode('.', $filterCallback) : $filterCallback) . "'"); } return array_filter($array, $filterCallback); } public static function filterNotEmpty($value) { return !empty($value); } public static function filterNotEmptyString($value) { if ('0' === $value) return true; return !empty($value); } public static function filterInteger($value) {// An integer or string with integer value if (is_int($value)) { return true; } else if (is_string($value)) { if ((string)(int)$value === $value) { return true; } } return false; } public static function filterNegativeInteger($value) {// An integer containing only negative values (..,-2,-1) if (V::filterInteger($value)) { if (intval($value) < 0) { return true; } } return false; } public static function filterNonNegativeInteger($value) {// An integer containing only non-negative values (0,1,2,..) if (V::filterInteger($value)) { if (intval($value) >= 0) { return true; } } return false; } public static function filterNonPositiveInteger($value) {// An integer containing only non-positive values (..,-2,-1,0) if (V::filterInteger($value)) { if (intval($value) <= 0) { return true; } } return false; } public static function filterPositiveInteger($value) {// An integer containing only positive values (1,2,..) if (V::filterInteger($value)) { if (intval($value) > 0) { return true; } } return false; } public static function validate($argName, $args, $params) { //$what = V::validate('what', $args, array('type'=>'word', 'not_empty'=>true, 'max_length'=>'255', 'values'=>$when_values)); $argValue = V::get($argName, null, $args); $fldLabel = V::get('fld_label', $argName, $params); if (array_key_exists('not_empty', $params) && true == $params['not_empty']) { if (!array_key_exists($argName, $args) || empty($args[$argName])) throw new Exception("Field {$fldLabel} not set."); } $params['fld_label'] = $fldLabel; return V::validateValue($argValue, $params); } public static function validateValue($value, $params) { $fldLabel = V::get('fld_label', '', $params); $maxLength = V::get('max_length', 0, $params); if ($maxLength > 0) { if (strlen($value) > $maxLength) throw new Exception("'{$fldLabel}' cannot be longer then {$maxLength}."); } $allowedValues = V::get('values', null, $params); if (is_array($allowedValues) && !empty($allowedValues)) { if (!in_array($value, $allowedValues)) throw new Exception("'{$fldLabel}' value is not allowed"); } $type = V::get('type', null, $params); if ($type != null) { if ('word' == $type) { if (!is_scalar($value) || !preg_match('/^[a-zA-Z_-]*$/', $value)) throw new Exception("required type '{$type}' ({$fldLabel})"); } else if ('login' == $type) { if (!is_scalar($value) || !preg_match('/^[a-zA-Z\._-]*$/', $value)) throw new Exception("required type '{$type}' ({$fldLabel})"); } else { throw new Exception("Unimplemented type to validate: '{$type}'"); } } if (array_key_exists('equal', $params)) { if ($value != $params['equal']) throw new Exception(V::get('error_msg_equal', "'{$fldLabel}' must be equal to '{$params['equal']}'", $params)); } if (array_key_exists('equalStrict', $params)) { if ($value !== $params['equalStrict']) throw new Exception(V::get('error_msg_equalStrict', "'{$fldLabel}' must be strict equal to '{$params['equal']}'", $params)); } return $value; } public static function exec($cmd, &$out, &$ret) { $out = null; $ret = null; // NOTE: SourceGuardian requires file: "${HOME}/.config/SourceGuardian/" $cmd = implode("\n", [ "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", "export HOME='/Library/WebServer'", $cmd ]); exec($cmd, $out, $ret); return $ret; } static function shell_exec($cmd) { $out = null; $ret = null; // NOTE: SourceGuardian requires file: "${HOME}/.config/SourceGuardian/" $cmd = implode("\n", [ "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", "export HOME='/Library/WebServer'", $cmd ]); return shell_exec($cmd); } public static function execRemote($host, $login, $password, $command, &$out, &$ret, $port = 22) { $out = null; $ret = null; $pass = $password; $pass = str_replace('!', '\!', $pass); $sshPort = (22 != $port)? "-p {$port}" : ''; $cmd = '/opt/local/bin/sshpass -p ' . $pass . ' ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=99999 ' . $sshPort . ' ' . $login . '@' . $host . ' -t < array("UNIT" => "TB", "VALUE" => pow(1024, 4)), 1 => array("UNIT" => "GB", "VALUE" => pow(1024, 3)), 2 => array("UNIT" => "MB", "VALUE" => pow(1024, 2)), 3 => array("UNIT" => "KB", "VALUE" => 1024), 4 => array("UNIT" => "B", "VALUE" => 1) ); foreach($arBytes as $arItem) { if ($bytes >= $arItem["VALUE"]) { $result = $bytes / $arItem["VALUE"]; $result = str_replace(".", "," , strval(round($result, 2)))." ".$arItem["UNIT"]; break; } } return $result; } public static function kwotaSlownie($kwota = 0, $waluta = "PLN") { if (!preg_match("/^[[:digit:]]*(\.[[:digit:]]+)?$/",$kwota)) throw new Exception("Błędna liczba"); if (!preg_match("/^[[:digit:]]{0,48}(\.[[:digit:]]+)?$/",$kwota)) throw new Exception("Zbyt duża liczba"); $waluty = array( 'PLN' => array('złoty','złotych','złote'), 'USD' => array('dolar','dolarów','dolary') ); $jednosci = array('zero','jeden','dwa','trzy','cztery','pięć','sześć','siedem','osiem','dziewięć','dziesięć','jedenaście', 'dwanaście','trzynaście','czternaście','piętnaście','szesnaście','siednaście','osiemnaście','dziewiętnaście'); $dziesiatki = array('','','dwadzieścia','trzydzieści','czterdzieści','pięćdziesiąt','sześćdziesiąt','siedemdziesiąt','osiemdziesiąt','dziewięćdziesiąt'); $setki = array('','sto','dwieście','trzysta','czterysta','pięćset','sześćset','siedemset','osiemset','dziewięćset'); if (!isset($waluty[$waluta])) $tysiace[] = array($waluta,$waluta,$waluta); else $tysiace[] = $waluty[$waluta]; $tysiace[] = array('tysiąc','tysięcy','tysiące'); $tysiace[] = array('milion','milionów','miliony'); $tysiace[] = array('miliard','miliardów','miliardy'); $tysiace[] = array('bilion','bilionów','bilony'); $tysiace[] = array('biliard','biliardów','biliardy'); $tysiace[] = array('trylion','trylionów','tryliony'); $tysiace[] = array('tryliard','tryliardów','tryliardy'); $tysiace[] = array('kwadrylion','kwadrylionów','kwadryliony'); $tysiace[] = array('kwadryliard','kwadryliardów','kwaryliardy'); $tysiace[] = array('kwintylion','kwintylionów','kwintyliony'); $tysiace[] = array('kwintyliard','kwintyliardów','kwintyliardy'); $tysiace[] = array('sekstylion','sekstylionów','sepstyliony'); $tysiace[] = array('sekstyliard','sekstyliardów','sekstyliardy'); $tysiace[] = array('septylion','septylionów','septyliony'); $tysiace[] = array('septyliard','septyliardów','septyliardy'); $kwota = (!substr_count($kwota, '.')) ? $kwota.'.00' : $kwota; list($zlote, $grosze) = explode('.', $kwota); $zlote = ltrim($zlote, '0'); if ($zlote == '') $zlote = '0'; if (strlen($grosze) == 1) $grosze .= "0"; elseif (strlen($grosze) > 2) $grosze = round(substr($grosze, 0, 2).".".substr($grosze, 2), 0); $zlote = strrev(wordwrap(strrev($zlote), 3, '.', true)); $zloteArr = explode('.', $zlote); foreach ($zloteArr as $i => $l) { $tysiac = count($zloteArr) - $i - 1; $setka = $setki[floor($l/100)]; $dziesiatka = $dziesiatki[floor(($l%100)/10)]; $jednosc = $dziesiatka ? $jednosci[$l%10] : $jednosci[$l%100]; if ($l == 1 and ($tysiac > 0 or count($zloteArr) == 1)) $odmiana = 0; elseif (floor($l%100/10) != 1 and $l%10 >= 2 and $l%10 <= 4) $odmiana = 2; else $odmiana = 1; if ($setka) $resultArr[] = $setka; if ($dziesiatka) $resultArr[] = $dziesiatka; if ($jednosc == $jednosci[0] && $zlote != '0') $jednosc = ''; if ($jednosc) $resultArr[] = $jednosc; if ($setka || $dziesiatka || $jednosc || $tysiac == 0) $resultArr[] = $tysiace[$tysiac][$odmiana]; } $resultArr[] = $grosze . "/100"; return implode(" ", $resultArr); } public static function nettoOdBrutto($brutto = 0, $vat = "23") { if ($vat < 0) throw new Exception("Stawka VAT nie może być liczbą ujemną!"); $netto = round($brutto/(1+$vat/100),2); if (round($netto*(1+$vat/100),2) > $brutto) $netto -= 0.01; return $netto; } public static function makePick($fieldName, $default = '', $type = null) { return function ($item) use ($fieldName, $default, $type) { return V::get($fieldName, $default, $item, $type); }; } public static function makeSplit($splitChar, $total) { return function ($string) use ($splitChar, $total) { return ($total) ? explode($splitChar, $string, $total) : explode($splitChar, $string); }; } public static function makeJoin($joinChar) { return function ($string) use ($joinChar) { return implode($joinChar, $string); }; } public static function pickSimgleValue($items, $fieldName) { return array_map( function ($row) use ($fieldName) { return V::get($fieldName, '', $row); } , $items ); } public static function pickArrayValues($items, $fieldNames) { return $items; } static function addSingleQuotes($str) { return "'{$str}'"; } public static function arrayToXML($array, $formatOutput = false, $root = "root") { $arrayToXML_rec = function($data, $dom, $node, $parent = null) use (&$arrayToXML_rec) { $child = $dom->createElement($node); if (!$parent) $parent = $dom; if (is_array($data)) { if ($data) { foreach ($data as $key => $value) { if ((string)$key === '@attributes') { foreach ($value as $attrName => $attrValue) { $attr = $dom->createAttribute($attrName); $attr->value = $attrValue; $child->appendChild($attr); } } else { if (is_numeric($key)) $arrayToXML_rec($value, $dom, $node, $parent); else $arrayToXML_rec($value, $dom, $key, $child); } } } else $parent->appendChild($child); } else { if ($data) { if ($data == htmlspecialchars($data)) $child->nodeValue = $data; else $child->appendChild($dom->createCDATASection($data)); } else $parent->appendChild($child); } if ($child->hasChildNodes() || $child->hasAttributes()) $parent->appendChild($child); }; if (!is_array($array)) throw new Exception("First argument need to be an array"); $dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->formatOutput = $formatOutput; $arrayToXML_rec($array, $dom, $root); return $dom->saveXML(); } // date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6), // a: '2017-07-25 13:06:15.59124', // b: '2017-07-25 13:06:15.56161', // result: '0.02963' public static function milisecondsStringDiff($a, $b) { if (25 != strlen($a)) return "Wrong length in 1st arg"; if (25 != strlen($b)) return "Wrong length in 2nd arg"; $aTime = array_sum([ intVal(substr($a, 11, 2)) * 100000 * 60 * 60, // hour intVal(substr($a, 14, 2)) * 100000 * 60, // min intVal(substr($a, 17, 2)) * 100000, // sec intVal(substr($a, 20, 5)), // mili sec (5 digits) ]); $bTime = array_sum([ intVal(substr($b, 11, 2)) * 100000 * 60 * 60, // hour intVal(substr($b, 14, 2)) * 100000 * 60, // min intVal(substr($b, 17, 2)) * 100000, // sec intVal(substr($b, 20, 5)), // mili sec (5 digits) ]); return sprintf("%0.5f", abs($aTime - $bTime) / 100000); } public static function isNip($nip) { if (!(is_numeric($nip) && preg_match('/^[[:digit:]]{10}$/', $nip))) return false; $waga = [6, 5, 7, 2, 3, 4, 5, 6, 7]; $c = 0; for ($i = 0; $i < 9; $i++) $c += $nip[$i] * $waga[$i]; $c = ($c % 11) % 10; return ($nip[9] == $c); } public static function isRegon($regon) { if (!(is_numeric($regon) && preg_match('/^[[:digit:]]{9}$/', $regon))) return false; $waga = [8, 9, 2, 3, 4, 5, 6, 7]; $c = 0; for ($i = 0; $i < 8; $i++) $c += $regon[$i] * $waga[$i]; $c = ($c % 11) % 10; return ($regon[8] == $c); } static function stripInvalidXmlChars($value = "") { return array_reduce(str_split((string)$value), function ($ret, $char) { $charCode = ord($char); if ( (0x9 === $charCode) || (0xA === $charCode) || (0xD === $charCode) || (($charCode >= 0x20) && ($charCode <= 0xD7FF)) || (($charCode >= 0xE000) && ($charCode <= 0xFFFD)) || (($charCode >= 0x10000) && ($charCode <= 0x10FFFF)) ) { return $ret . $char; } return $ret; }, ""); } static function fixUtf8ToHtmlChars($input) { $input = self::stripInvalidXmlChars($input); $input = self::fixUtf8ToHtmlChar($input, 'µ', 'µ'); $input = self::fixUtf8ToHtmlChar($input, 'φ', 'φ'); $input = self::fixUtf8ToHtmlChar($input, 'Φ', 'Φ'); $input = self::fixUtf8ToHtmlChar($input, '–', '-'); //$input = $this->fixUtf8ToHtmlChar($input, '°', '°');// ° is ok in latin2 return $input; } static function fixUtf8ToHtmlChar($input, $from, $to) { if (function_exists('mb_split') && false !== ($pos = mb_strpos($input, $from, 0, 'utf-8'))) { return implode($to, mb_split($from, $input)); } return $input; } static function deleteWholeDirectory($dir, $returnFiles = false, $doDelete = true) { if (!is_dir($dir)) throw new Exception("{$dir} must be a directory"); $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); if ($doDelete) { $rmdir = 'rmdir'; $unlink = 'unlink'; } else { $rmdir = 'is_string'; $unlink = 'is_string'; } if ($returnFiles) { $return = []; foreach ($files as $file) { if ($file->isDir()) $return['dirs'][$file->getRealPath()] = @$rmdir($file->getRealPath()); else $return['files'][$file->getRealPath()] = @$unlink($file->getRealPath()); } $return['dirs'][$dir] = @$rmdir($dir); return $return; } else { foreach ($files as $file) { if ($file->isDir()) @$rmdir($file->getRealPath()); else @$unlink($file->getRealPath()); } @$rmdir($dir); } } static function glob($pattern, $flags = 0) { $ret = glob($pattern, $flags); return (false === $ret) ? [] : $ret; } static function tryHandleException(callable $handler, callable $callback, array $args = []) { // try again on exception try { return call_user_func_array($callback, $args); } catch (Exception $e) { DBG::log("DBG:V->tryHandleException Exception trying to fix using handler ..."); DBG::log($e); $handler($e); return call_user_func_array($callback, $args); } } // @param $callback must return bool function arrayFindFirst(array $input, callable $callback) { // @return found index or -1 if not found $idx = -1; foreach ($input as $idx => $item) { if ($callback($item)) return $idx; } return $idx; } }