Files
cmp-php-util/cmpUtil.php
T
2023-08-23 21:00:54 +12:00

665 lines
13 KiB
PHP

<?php
trait cmpUtil {
var $gitStatus = "Unknown";
var $gitDate = "";
var $gitTime = "";
var $gitTimeStamp = "";
var $gitCommit = "";
var $gitComment = "";
function toArray($obj) {
$re = array();
$in = null;
if(is_array($obj))
$in = $obj;
if(is_object($obj))
$in = get_object_vars($obj);
if(is_string($obj)) return $obj;
if(is_float($obj)) return $obj;
if(is_bool($obj)) return $obj;
if(is_int($obj)) return $obj;
foreach((array) $in as $k => $v) {
if(is_array($in[$k])) {
// echo "$k array\n";
$re[$k] = $this->toArray($v);
continue;
}
if(is_object($in[$k])) {
// echo "$k object\n";
$re[$k] = $this->toArray($v);
continue;
}
// echo "$k string?\n";
$re[$k] = $v;
}
return $re;
}
function errorJSON($err, $f = 2) {
switch($err) {
case JSON_ERROR_NONE : $this->e('Ошибок нет' , $f); break;
case JSON_ERROR_DEPTH : $this->e('Достигнута максимальная глубина стека' , $f); break;
case JSON_ERROR_STATE_MISMATCH : $this->e('Некорректные разряды или не совпадение режимов' , $f); break;
case JSON_ERROR_CTRL_CHAR : $this->e('Некорректный управляющий символ' , $f); break;
case JSON_ERROR_SYNTAX : $this->e('Синтаксическая ошибка, не корректный JSON' , $f); break;
case JSON_ERROR_UTF8 : $this->e('Некорректные символы UTF-8, возможно неверная кодировка' , $f); break;
case JSON_ERROR_RECURSION : $this->e('Одна или несколько зацикленных ссылок в кодируемом значении' , $f); break;
case JSON_ERROR_INF_OR_NAN : $this->e('Одно или несколько значений NAN или INF в кодируемом значении' , $f); break;
case JSON_ERROR_UNSUPPORTED_TYPE : $this->e('Передано значение с неподдерживаемым типом' , $f); break;
case JSON_ERROR_INVALID_PROPERTY_NAME : $this->e('Имя свойства не может быть закодировано' , $f); break;
case JSON_ERROR_UTF16 : $this->e('Некорректный символ UTF-16, возможно некорректно закодирован' , $f); break;
default : $this->e('Неизвестная ошибка' , $f); break;
}
}
function decodeJSONRaw($str, $f = 2) {
$obj = json_decode(
$str , // string $json
true , // ?bool $associative = null
512 , // int $depth = 512
JSON_INVALID_UTF8_IGNORE // int $flags = 0
);
$err = json_last_error();
if($err === JSON_ERROR_NONE)
return $this->toArray($obj);
$this->errorJSON($err, $f + 1);
$this->d("Invalid JSON: " . $str, $f);
return null;
}
function decodeJSON($str, $d = 0) {
$m = array();
// eq '/[[:cntrl:]]/u';
// $re = '/[\x00-\x1F\x7F]/u';
// Add ignore 0x09, 0x0a, 0x0d
$re = '/[\x00-\x08\x0b-\x0c\x0e-\x1F\x7F]/u';
// $ign = array("0x09", "0x0a", "0x0d");
if(preg_match_all($re, $str, $m)) {
$tr = array();
for($i = 0; $i < count($m[0]); $i++) {
$bin = $m[0][$i];
if(isset($tr[$bin]))
continue;
$hex = "0x" . bin2hex($bin);
// if(in_array($hex, $ign))
// continue;
$tr[$bin] = $hex;
if($d)
$this->d("decodeJSON: Translate " . $hex);
}
$str = strtr($str, $tr);
}
return $this->decodeJSONRaw($str, 6);
}
function encodeJSON($obj) {
$text = json_encode($obj, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$err = json_last_error();
if($err === JSON_ERROR_NONE)
return $text;
$this->errorJSON($err);
return null;
}
function encodeJSONCompact($obj) {
$text = json_encode($obj, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$err = json_last_error();
if($err === JSON_ERROR_NONE)
return $text;
$this->errorJSON($err);
return null;
}
function readFile($file) {
return @file_get_contents(
$file , // string
false , // bool $use_include_path
null , // ?resource $context
0 , // int $offset
$this->parm["maxFileSize"] , // ?int $length
);
}
function readJSON($file) {
$raw = $this->readFile($file);
if(!$raw) {
$this->e("Can't read '$file'");
return false;
}
$obj = $this->decodeJSON($raw, 1);
if(!$obj) {
$this->e("Invalid JSON '$file'");
return false;
}
// var_export($obj);
return $obj;
}
function appendConf($arr) {
if(!$arr)
return false;
foreach($arr as $k => $v) {
// $this->d("Set parm .$k to $v");
$this->parm[$k] = $v;
}
return true;
}
function readJSONConf($file) {
$obj = $this->readJSON($file);
if(!$obj)
return false;
$this->appendConf($obj);
if(@$this->parm["timezone"]) {
$this->d("Set timezone '" . $this->parm["timezone"] . "'");
date_default_timezone_set($this->parm["timezone"]);
}
if(!@$this->parm["maxFileSize"])
$this->parm["maxFileSize"] = 1048576;
$this->d("Set maxFileSize '" . $this->parm["maxFileSize"] . "'");
if(is_array(@$this->parm["php_ini"])) {
foreach($this->parm["php_ini"] as $k => $v) {
ini_set($k, $v);
}
}
return true;
}
function fgExec($cmd) {
$cmd .= " 2>/tmp/fgExec.err";
$this->d("fgExec: $cmd");
ob_start();
passthru($cmd, $ret);
$out = ob_get_contents();
ob_end_clean();
$a = array(
"return" => $ret,
"stderr" => array(),
"output" => $out
);
$ff = "/tmp/fgExec.err";
$err = @file($ff);
// var_export($err);
if(!is_array($err)) {
$a["stderr"][] = "Can't read file: $ff";
}
else for($i = 0; $i < count($err); $i++) {
$str = trim($err[$i], "\r\n");
// $this->d($str);
$a["stderr"][] = $str;
}
@unlink("/tmp/fgExec.err");
return $a;
}
function cmpShellEscStr($str) {
$ttr = array(
"\t" => "\\\t", "\$" => "\\\$",
"\\" => "\\\\", "\"" => "\\\"",
" " => "\\ " , "`" => "\\`",
"#" => "\\#" , "&" => "\\&",
"(" => "\\(" , ")" => "\\)",
"*" => "\\*" , "|" => "\\|",
"[" => "\\[" , "]" => "\\]",
"{" => "\\{" , "}" => "\\}",
";" => "\\;" , "'" => "\\'",
"<" => "\\<" , ">" => "\\>",
"?" => "\\?" , "!" => "\\!"
);
if(@$str[0] == "asis")
return @$str[1];
return strtr($str, $ttr);
}
function cmpShellEscArr($cmaRaw) {
$cmaEsc = array();
for($i = 0; $i < count($cmaRaw); $i++) {
$cmaEsc[] = $this->cmpShellEscStr($cmaRaw[$i]);
}
return $cmaEsc;
}
function cmpShellEsc($cmaRaw) {
if(is_array($cmaRaw)) {
$cmaEsc = $this->cmpShellEscArr($cmaRaw);
return join(" ", $cmaEsc);
}
return $this->cmpShellEscStr($cmaRaw);
}
function cmpSysExec($cmaRaw, $opt = []) {
$cmdStr = $this->cmpShellEscStr($cmaRaw);
if(!@$opt["silent"]) {
$this->d("cmpSysExec: " . $cmdStr);
}
$fdsAll = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$workDir = "/tmp";
if(@$opt["workDir"])
$workDir = $opt["workDir"];
$envAll = null;
$ppsAll = array();
$prcRes = proc_open($cmdStr, $fdsAll, $ppsAll, $workDir, $envAll);
if(!is_resource($prcRes)) {
$this->e("Can't create process");
return null;
}
$blk = 1;
if(isset($opt["blocking"])) {
$blk = $opt["blocking"];
}
stream_set_blocking($ppsAll[1], $blk);
stream_set_blocking($ppsAll[2], $blk);
$retVal = 255;
$out = "";
$err = "";
if($blk) {
if(@$opt["stdin"]) {
fwrite($ppsAll[0], $opt["stdin"]);
fclose($ppsAll[0]);
}
if(@$opt["stdOutRead"]) {
$this->d("Read loop");
while(!feof($ppsAll[1])) {
$out = stream_get_contents($ppsAll[1], 1048576);
// $err = stream_get_contents($ppsAll[2], 1048576);
($opt["stdOutRead" ]["call"]) (
$out,
$opt["stdOutRead"]
);
}
}
else {
$out = stream_get_contents($ppsAll[1], 1048576);
$err = stream_get_contents($ppsAll[2], 1048576);
}
fclose($ppsAll[1]);
fclose($ppsAll[2]);
}
else {
// $this->d("Nonblock");
do {
if(!@$opt["stdInEventAdd"])
break;
if(!is_callable(@$opt["stdInEventAdd"]["call"])) {
$this->d("Invalid callable stdInEventAdd");
break;
}
if(!@$opt["silent"])
$this->d("Call stdInEventAdd");
($opt["stdInEventAdd"]["call"]) (
$ppsAll[0],
$opt["stdInEventAdd"]
);
} while(0);
do {
if(!@$opt["stdOutEventAdd"])
break;
if(!is_callable(@$opt["stdOutEventAdd"]["call"])) {
$this->d("Invalid callable stdOutEventAdd");
break;
}
if(!@$opt["silent"])
$this->d("Call stdOutEventAdd");
($opt["stdOutEventAdd" ]["call"]) (
$ppsAll[1],
$opt["stdOutEventAdd"]
);
} while(0);
do {
if(!@$opt["stdErrEventAdd"])
break;
if(!is_callable(@$opt["stdErrEventAdd"]["call"])) {
$this->d("Invalid callable stdErrEventAdd");
break;
}
if(!@$opt["silent"])
$this->d("Call stdErrEventAdd");
($opt["stdErrEventAdd"]["call"]) (
$ppsAll[2],
$opt["stdErrEventAdd"]
);
} while(0);
do {
if(!@$opt["eventWait"])
break;
if(!@$opt["silent"])
$this->d("Call eventWait");
if(!is_callable(@$opt["eventWait"]["call"])) {
$this->d("Invalid callable eventWait");
break;
}
($opt["eventWait"]["call"])();
} while(0);
}
$retVal = proc_close($prcRes);
if(!@$opt["return"] || @$opt["return"] == "full") {
return array(
"retval" => $retVal,
"stdout" => $out,
"stderr" => $err
);
}
$val = 0;
if(@$opt["retval"])
$val = $opt["retval"];
if(!@$opt["noerror"]) {
if($retVal !== $val) {
if(!@$opt["silent"]) {
$this->d($err);
$this->d("Return code: " . $retVal);
}
return null;
}
if($err) {
$this->d($err);
}
}
switch(@$opt["return"]) {
case "retval":
return 1*$retVal;
case "outstr":
return $out;
case "outarr":
default:
return explode("\n", $out);
}
return explode("\n", $out);
}
function getGitStatus() {
$ret = $this->fgExec("git status");
// $this->d(join("\n", $ret));
$out = trim($ret["output"], "\n \t\r");
if(!$out) {
$this->d($ret["stderr"][0]);
return false;
}
$lin = explode("\n", $out);
$cnt = count($lin);
if($lin[$cnt-1] == "nothing to commit, working tree clean") {
$this->gitStatus = "treeClean";
$this->d("Git tree clean");
} else {
$this->gitStatus = "treeModified";
$this->d("Last string: " . $lin[$cnt-1]);
}
return;
}
function getGitLog1() {
$ret = $this->fgExec("git log -1");
// $this->d(join("\n", $ret));
$out = trim($ret["output"], "\n \t\r");
if(!$out) {
$this->d($ret["stderr"][0]);
return false;
}
$lin = explode("\n", $out);
$cnt = count($lin);
$wrd = explode(" ", $lin[0]);
$this->gitCommit = $wrd[1];
$this->gitComment = $lin[$cnt-1];
$wrd = explode(" ", $lin[2]);
array_shift($wrd);
$this->gitTimeStamp = strtotime(join(" ", $wrd));
return;
}
function isMD5($str) {
if(preg_match("/^[0-9a-f]{32}$/", $str))
return true;
return false;
}
function isUNID($str) {
return $this->isMD5($str);
}
function isDateFT($str) {
if(preg_match("/^(20[0-9]{2}-[01][0-9]-[0-3][0-9]) ([0-2][0-9]:[0-5][0-9]:[0-5][0-9])$/", $str))
return true;
return false;
}
function isP7Phone($str) {
if(preg_match("/^\+7(9[0-9]{2})([0-9]{7})$/", $str))
return true;
return false;
}
function isPxPhone($str) {
if(preg_match("/^\+7(9[0-9]{2})([0-9]+)$/", $str)) {
return true;
}
if(preg_match("/^\+([0-9]+)$/", $str)) {
$this->d("Wild number $str");
return true;
}
return false;
}
function normalizePhone($inp) {
if(preg_match("/^((\+7)|8)?(\d{3})(\d{7,8})$/", $inp, $m)) {
return "+7" . $m[3] . $m[4];
}
return null;
}
function isINN($inn) {
$inn = (string) $inn;
if(!preg_match("/^[0-9]{10,12}$/", $inn)) {
return null;
}
switch(strlen($inn)) {
case 10:
$n = 0;
foreach([2, 4, 10, 3, 5, 9, 4, 6, 8] as $i => $k) {
$n += $k * (int) $inn[$i];
}
$n10 = $n % 11 % 10;
if($n10 === (int) $inn[9])
return true;
return false;
case 12:
$n = 0;
foreach([7, 2, 4, 10, 3, 5, 9, 4, 6, 8] as $i => $k) {
$n += $k * (int) $inn[$i];
}
$n11 = $n % 11 % 10;
$n = 0;
foreach([3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8] as $i => $k) {
$n += $k * (int) $inn[$i];
}
$n12 = $n % 11 % 10;
if(($n11 === (int) $inn[10]) && ($n12 === (int) $inn[11]))
return true;
return false;
}
return false;
}
function isSnils($snils) {
$snils = (string) $snils;
if(!preg_match("/^[0-9]{11}$/", $snils)) {
return null;
}
$sum = 0;
for($i = 0; $i < 9; $i++) {
$sum += (int) $snils[$i] * (9 - $i);
}
$cs = 0;
if ($sum < 100) {
$cs = $sum;
} elseif ($sum > 101) {
$cs = $sum % 101;
if ($cs === 100) {
$cs = 0;
}
}
if($cs === (int) substr($snils, -2)) {
return true;
}
return false;
}
// END
}
?>