Add src files for CoreLibs composer all package

This commit is contained in:
Clemens Schwaighofer
2023-02-16 12:47:43 +09:00
commit cfcd601b3a
76 changed files with 25404 additions and 0 deletions

167
src/Convert/Byte.php Normal file
View File

@@ -0,0 +1,167 @@
<?php
/*
* byte conversion from and to human readable
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Byte
{
// define byteFormat
public const BYTE_FORMAT_NOSPACE = 1;
public const BYTE_FORMAT_ADJUST = 2;
public const BYTE_FORMAT_SI = 4;
/**
* This function replaces the old byteStringFormat
*
* Converts any number string to human readable byte format
* Maxium is Exobytes and above that the Exobytes suffix is used for all
* If more are needed only the correct short name for the suffix has to be
* added to the labels array
* On no number string it returns string as is
* Source Idea: SOURCE: https://programming.guide/worlds-most-copied-so-snippet.html
*
* The class itself hast the following defined
* BYTE_FORMAT_NOSPACE [1] turn off spaces between number and suffix
* BYTE_FORMAT_ADJUST [2] use sprintf to always print two decimals
* BYTE_FORMAT_SI [4] use si standard 1000 instead of bytes 1024
* To use the constant from outside use class::CONSTANT
*
* @param string|int|float $bytes bytes as string int or pure int
* @param int $flags bitwise flag with use space turned on
* BYTE_FORMAT_NOSPACE: no space between number and suffix
* BYTE_FORMAT_ADJUST: sprintf adjusted two 2 decimals
* BYTE_FORMAT_SI: use 1000 instead of 1024
* @return string converted byte number (float) with suffix
* @throws \Exception 1: no valid flag set
*/
public static function humanReadableByteFormat($bytes, int $flags = 0): string
{
// if not numeric, return as is
if (is_numeric($bytes)) {
// flags bit wise check
// remove space between number and suffix
if ($flags & self::BYTE_FORMAT_NOSPACE) {
$space = false;
} else {
$space = true;
}
// use sprintf instead of round
if ($flags & self::BYTE_FORMAT_ADJUST) {
$adjust = true;
} else {
$adjust = false;
}
// use SI 1000 mod and not 1024 mod
if ($flags & self::BYTE_FORMAT_SI) {
$si = true;
} else {
$si = false;
}
if ($flags > 7) {
throw new \Exception("Invalid flags parameter: $flags", 1);
}
// si or normal
$unit = $si ? 1000 : 1024;
// always positive
$abs_bytes = $bytes == PHP_INT_MIN ? PHP_INT_MAX : abs((float)$bytes);
// smaller than unit is always B
if ($abs_bytes < $unit) {
return $bytes . 'B';
}
// labels in order of size [Y, Z]
$labels = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
// exp position calculation
$exp = floor(log($abs_bytes, $unit));
// avoid printing out anything larger than max labels
if ($exp >= count($labels)) {
$exp = count($labels) - 1;
}
// deviation calculation
$dev = pow($unit, $exp) * ($unit - 0.05);
// shift the exp +1 for on the border units
if (
$exp < 6 &&
$abs_bytes > ($dev - (((int)$dev & 0xfff) == 0xd00 ? 52 : 0))
) {
$exp++;
}
// label name, including leading space if flagged
$pre = ($space ? ' ' : '') . ($labels[$exp] ?? '>E') . ($si ? 'i' : '') . 'B';
$bytes_calc = $abs_bytes / pow($unit, $exp);
// if original is negative, reverse
if ($bytes < 0) {
$bytes_calc *= -1;
}
if ($adjust) {
return sprintf("%.2f%s", $bytes_calc, $pre);
} else {
return round($bytes_calc, 2) . $pre;
}
} else {
// if anything other return as string
return (string)$bytes;
}
}
/**
* calculates the bytes based on a string with nnG, nnGB, nnM, etc
* NOTE: large exabyte numbers will overflow
* flag allowed:
* BYTE_FORMAT_SI [4] use si standard 1000 instead of bytes 1024
*
* @param string|int|float $number any string or number to convert
* @param int $flags bitwise flag with use space turned on
* BYTE_FORMAT_SI: use 1000 instead of 1024
* @return string|int|float converted value or original value
* @throws \Exception 1: no valid flag set
*/
public static function stringByteFormat($number, int $flags = 0)
{
// use SI 1000 mod and not 1024 mod
if ($flags & self::BYTE_FORMAT_SI) {
$si = true;
} else {
$si = false;
}
if ($flags != 0 && $flags != 4) {
throw new \Exception("Invalid flags parameter: $flags", 1);
}
// matches in regex
$matches = [];
// all valid units
$valid_units_ = 'bkmgtpezy';
// detects up to exo bytes
preg_match(
"/(-)?([\d.,]*)\s?(eib|pib|tib|gib|mib|kib|eb|pb|tb|gb|mb|kb|e|p|t|g|m|k|b)$/i",
strtolower((string)$number),
$matches
);
if (isset($matches[2]) && isset($matches[3])) {
// remove all non valid characters from the number
$number = preg_replace('/[^0-9\.]/', '', $matches[2]);
// final clean up and convert to float
$number = (float)trim((string)$number);
// convert any mb/gb/etc to single m/b
$unit = preg_replace('/[^bkmgtpezy]/i', '', $matches[3]);
if ($unit) {
$number = $number * pow($si ? 1000 : 1024, stripos($valid_units_, $unit[0]) ?: 0);
}
// convert to INT to avoid +E output
$number = (int)round($number);
// if negative input, keep nnegative
if (!empty($matches[1])) {
$number *= -1;
}
}
// if not matching return as is
return $number;
}
}
// __END__

344
src/Convert/Colors.php Normal file
View File

@@ -0,0 +1,344 @@
<?php
/*
* Convert color spaces
* rgb to hex
* hex to rgb
* rgb to hsb
* hsb to rgb
* rgb to hsl
* hsl to rgb
*/
// TODO: use oklab as base for converting colors
// https://bottosson.github.io/posts/oklab/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Colors
{
/**
* converts the rgb values from int data to the valid rgb html hex string
* optional can turn of leading #
* if one value is invalid, will return false
*
* @param int $red red 0-255
* @param int $green green 0-255
* @param int $blue blue 0-255
* @param bool $hex_prefix default true, prefix with "#"
* @return string|bool rgb in hex values with leading # if set,
* false for invalid color
*/
public static function rgb2hex(int $red, int $green, int $blue, bool $hex_prefix = true)
{
$hex_color = '';
if ($hex_prefix === true) {
$hex_color = '#';
}
foreach (['red', 'green', 'blue'] as $color) {
// if not valid, abort
if ($$color < 0 || $$color > 255) {
return false;
}
// pad left with 0
$hex_color .= str_pad(dechex($$color), 2, '0', STR_PAD_LEFT);
}
return $hex_color;
}
/**
* converts a hex RGB color to the int numbers
*
* @param string $hexStr RGB hexstring
* @param bool $return_as_string flag to return as string
* @param string $seperator string seperator: default: ","
* @return string|array<string,float|int>|bool false on error or array with RGB
* or a string with the seperator
*/
public static function hex2rgb(
string $hexStr,
bool $return_as_string = false,
string $seperator = ','
) {
$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); // Gets a proper hex string
if (!is_string($hexStr)) {
return false;
}
$rgbArray = [];
if (strlen($hexStr) == 6) {
// If a proper hex code, convert using bitwise operation.
// No overhead... faster
$colorVal = hexdec($hexStr);
$rgbArray['r'] = 0xFF & ($colorVal >> 0x10);
$rgbArray['g'] = 0xFF & ($colorVal >> 0x8);
$rgbArray['b'] = 0xFF & $colorVal;
} elseif (strlen($hexStr) == 3) {
// If shorthand notation, need some string manipulations
$rgbArray['r'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));
$rgbArray['g'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));
$rgbArray['b'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));
} else {
// Invalid hex color code
return false;
}
// returns the rgb string or the associative array
return $return_as_string ? implode($seperator, $rgbArray) : $rgbArray;
}
/**
* rgb2hsb does not clean convert back to rgb in a round trip
* converts RGB to HSB/V values
* returns:
* array with hue (0-360), sat (0-100%), brightness/value (0-100%)
*
* @param int $red red 0-255
* @param int $green green 0-255
* @param int $blue blue 0-255
* @return array<int|float>|bool Hue, Sat, Brightness/Value
* false for input value error
*/
public static function rgb2hsb(int $red, int $green, int $blue)
{
// check that rgb is from 0 to 255
foreach (['red', 'green', 'blue'] as $c) {
if ($$c < 0 || $$c > 255) {
return false;
}
$$c = $$c / 255;
}
$MAX = max($red, $green, $blue);
$MIN = min($red, $green, $blue);
$HUE = 0;
if ($MAX == $MIN) {
return [0, 0, round($MAX * 100)];
}
if ($red == $MAX) {
$HUE = ($green - $blue) / ($MAX - $MIN);
} elseif ($green == $MAX) {
$HUE = 2 + (($blue - $red) / ($MAX - $MIN));
} elseif ($blue == $MAX) {
$HUE = 4 + (($red - $green) / ($MAX - $MIN));
}
$HUE *= 60;
if ($HUE < 0) {
$HUE += 360;
}
return [
(int)round($HUE),
(int)round((($MAX - $MIN) / $MAX) * 100),
(int)round($MAX * 100)
];
}
/**
* hsb2rgb does not clean convert back to hsb in a round trip
* converts HSB/V to RGB values RGB is full INT
* if HSB/V value is invalid, sets this value to 0
*
* @param float $H hue 0-360 (int)
* @param float $S saturation 0-100 (int)
* @param float $V brightness/value 0-100 (int)
* @return array<int>|bool 0 red/1 green/2 blue array as 0-255
* false for input value error
*/
public static function hsb2rgb(float $H, float $S, float $V)
{
// check that H is 0 to 359, 360 = 0
// and S and V are 0 to 1
if ($H == 360) {
$H = 0;
}
if ($H < 0 || $H > 359) {
return false;
}
if ($S < 0 || $S > 100) {
return false;
}
if ($V < 0 || $V > 100) {
return false;
}
// convert to internal 0-1 format
$S /= 100;
$V /= 100;
if ($S == 0) {
$V = (int)round($V * 255);
return [$V, $V, $V];
}
$Hi = floor($H / 60);
$f = ($H / 60) - $Hi;
$p = $V * (1 - $S);
$q = $V * (1 - ($S * $f));
$t = $V * (1 - ($S * (1 - $f)));
switch ($Hi) {
case 0:
$red = $V;
$green = $t;
$blue = $p;
break;
case 1:
$red = $q;
$green = $V;
$blue = $p;
break;
case 2:
$red = $p;
$green = $V;
$blue = $t;
break;
case 3:
$red = $p;
$green = $q;
$blue = $V;
break;
case 4:
$red = $t;
$green = $p;
$blue = $V;
break;
case 5:
$red = $V;
$green = $p;
$blue = $q;
break;
default:
$red = 0;
$green = 0;
$blue = 0;
}
return [
(int)round($red * 255),
(int)round($green * 255),
(int)round($blue * 255)
];
}
/**
* converts a RGB (0-255) to HSL
* return:
* array with hue (0-360), saturation (0-100%) and luminance (0-100%)
*
* @param int $red red 0-255
* @param int $green green 0-255
* @param int $blue blue 0-255
* @return array<float>|bool hue/sat/luminance
* false for input value error
*/
public static function rgb2hsl(int $red, int $green, int $blue)
{
// check that rgb is from 0 to 255
foreach (['red', 'green', 'blue'] as $c) {
if ($$c < 0 || $$c > 255) {
return false;
}
$$c = $$c / 255;
}
$min = min($red, $green, $blue);
$max = max($red, $green, $blue);
$chroma = $max - $min;
$sat = 0;
$hue = 0;
// luminance
$lum = ($max + $min) / 2;
// achromatic
if ($chroma == 0) {
// H, S, L
return [0.0, 0.0, round($lum * 100, 1)];
} else {
$sat = $chroma / (1 - abs(2 * $lum - 1));
if ($max == $red) {
$hue = fmod((($green - $blue) / $chroma), 6);
if ($hue < 0) {
$hue = (6 - fmod(abs($hue), 6));
}
} elseif ($max == $green) {
$hue = ($blue - $red) / $chroma + 2;
} elseif ($max == $blue) {
$hue = ($red - $green) / $chroma + 4;
}
$hue = $hue * 60;
// $sat = 1 - abs(2 * $lum - 1);
return [
round($hue, 1),
round($sat * 100, 1),
round($lum * 100, 1)
];
}
}
/**
* converts an HSL to RGB
* if HSL value is invalid, set this value to 0
*
* @param float $hue hue: 0-360 (degrees)
* @param float $sat saturation: 0-100
* @param float $lum luminance: 0-100
* @return array<int,float|int>|bool red/blue/green 0-255 each
*/
public static function hsl2rgb(float $hue, float $sat, float $lum)
{
if (!is_numeric($hue)) {
return false;
}
if ($hue == 360) {
$hue = 0;
}
if ($hue < 0 || $hue > 359) {
return false;
}
if ($sat < 0 || $sat > 100) {
return false;
}
if ($lum < 0 || $lum > 100) {
return false;
}
// calc to internal convert value for hue
$hue = (1 / 360) * $hue;
// convert to internal 0-1 format
$sat /= 100;
$lum /= 100;
// if saturation is 0
if ($sat == 0) {
$lum = (int)round($lum * 255);
return [$lum, $lum, $lum];
} else {
$m2 = $lum < 0.5 ? $lum * ($sat + 1) : ($lum + $sat) - ($lum * $sat);
$m1 = $lum * 2 - $m2;
$hueue = function ($base) use ($m1, $m2) {
// base = hue, hue > 360 (1) - 360 (1), else < 0 + 360 (1)
$base = $base < 0 ? $base + 1 : ($base > 1 ? $base - 1 : $base);
// 6: 60, 2: 180, 3: 240
// 2/3 = 240
// 1/3 = 120 (all from 360)
if ($base * 6 < 1) {
return $m1 + ($m2 - $m1) * $base * 6;
}
if ($base * 2 < 1) {
return $m2;
}
if ($base * 3 < 2) {
return $m1 + ($m2 - $m1) * ((2 / 3) - $base) * 6;
}
return $m1;
};
return [
(int)round(255 * $hueue($hue + (1 / 3))),
(int)round(255 * $hueue($hue)),
(int)round(255 * $hueue($hue - (1 / 3)))
];
}
}
}
// __END__

60
src/Convert/Encoding.php Normal file
View File

@@ -0,0 +1,60 @@
<?php
/*
* convert string frmo one encdoing to another with auto detect flags
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Encoding
{
/**
* detects the source encoding of the string and if doesn't match
* to the given target encoding it convert is
* if source encoding is set and auto check is true (default) a second
* check is done so that the source string encoding actually matches
* will be skipped if source encoding detection is ascii
*
* @param string $string string to convert
* @param string $to_encoding target encoding
* @param string $source_encoding optional source encoding, will try to auto detect
* @param bool $auto_check default true, if source encoding is set
* check that the source is actually matching
* to what we sav the source is
* @return string encoding converted string
*/
public static function convertEncoding(
string $string,
string $to_encoding,
string $source_encoding = '',
bool $auto_check = true
): string {
// set if not given
if (!$source_encoding) {
$source_encoding = mb_detect_encoding($string);
} else {
$_source_encoding = mb_detect_encoding($string);
}
if (
$auto_check === true &&
isset($_source_encoding) &&
$_source_encoding == $source_encoding
) {
// trigger check if we have override source encoding.
// if different (_source is all but not ascii) then trigger
// skip if matching
}
if ($source_encoding != $to_encoding) {
if ($source_encoding) {
$string = mb_convert_encoding($string, $to_encoding, $source_encoding);
} else {
$string = mb_convert_encoding($string, $to_encoding);
}
}
return $string;
}
}
// __END__

View File

@@ -0,0 +1,256 @@
<?php
/*
* Run is_<type> checks and return default value if not this type
* This will return default null on invalid entries
*/
declare(strict_types=1);
namespace CoreLibs\Convert\Extends;
class VarSetTypeMain
{
/**
* If input variable is string then returns it, else returns default set
* if not null is true, then null as return is allowed, else return is
* converted to string
*
* @param mixed $val Input variable
* @param string|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return string|null Input var or default value
*/
protected static function setStrMain(
mixed $val,
?string $default = null,
bool $to_null = false
): ?string {
if (is_string($val)) {
return $val;
}
if ($to_null === false) {
return (string)$default;
}
return $default;
}
/**
* Will convert input data to string if possible.
* Runs for string/int/float/bool/null
* Will skip array/object/resource/callable/etc and use default for that
*
* @param mixed $val Input variable
* @param string|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return string|null Converted input data to string/null
*/
protected static function makeStrMain(
mixed $val,
string $default = null,
bool $to_null = false
): ?string {
// int/float/string/bool/null, everything else is ignored
// no: array/object/resource/callable
if (
is_int($val) ||
is_float($val) ||
is_string($val) ||
is_bool($val) ||
is_null($val)
) {
return (string)$val;
}
if ($to_null === false) {
return (string)$default;
}
return $default;
}
/**
* If input variable is int, return it, else return default value. If to_null
* is true then null as return is allowed, else only int is returned
*
* @param mixed $val Input variable
* @param int|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return int|null Input var or default value
*/
protected static function setIntMain(
mixed $val,
?int $default = null,
bool $to_null = false
): ?int {
if (is_int($val)) {
return $val;
}
if ($to_null === false) {
return (int)$default;
}
return $default;
}
/**
* Convert input to int via filter_var. If not convertable return default value.
* If to_null is set to true null return is allowed
* NOTE: this is only a drastic fallback and not recommned for special use.
* It will try to check via filter_var if we can get an int value and then use
* intval to convert it.
* Reason is that filter_var will convert eg 1.5 to 15 instead 1
* One is very wrong, the other is at least better, but not perfect
*
* @param mixed $val Input variable
* @param int|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return int|null Converted input data to int/null
*/
protected static function makeIntMain(
mixed $val,
int $default = null,
bool $to_null = false
): ?int {
// if we can filter it to a valid int, we can convert it
// we so avoid object, array, etc
if (
filter_var(
$val,
FILTER_SANITIZE_NUMBER_INT
) !== false
) {
return intval($val);
}
if ($to_null === false) {
return (int)$default;
}
return $default;
}
/**
* If input is float return it, else set to default value. If to_null is set
* to true, allow null return
*
* @param mixed $val Input variable
* @param float|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return float|null Input var or default value
*/
protected static function setFloatMain(
mixed $val,
?float $default = null,
bool $to_null = false
): ?float {
if (is_float($val)) {
return $val;
}
if ($to_null === false) {
return (float)$default;
}
return $default;
}
/**
* Convert intput var to float via filter_var. If failed to so return default.
* If to_null is set to true allow null return
*
* @param mixed $val Input variable
* @param float|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return float|null Converted intput data to float/null
*/
protected static function makeFloatMain(
mixed $val,
float $default = null,
bool $to_null = false
): ?float {
if (
(
$val = filter_var(
$val,
FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_FRACTION
)
) !== false
) {
return (float)$val;
}
if ($to_null === false) {
return (float)$default;
}
return $default;
}
/**
* If input var is array return it, else return default value. If to_null is
* set to true, allow null return
*
* @param mixed $val Input variable
* @param array<mixed>|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return array<mixed>|null Input var or default value
*/
protected static function setArrayMain(
mixed $val,
?array $default = null,
bool $to_null = false
): ?array {
if (is_array($val)) {
return $val;
}
if ($to_null === false) {
return (array)$default;
}
return $default;
}
/**
* If input var is bool return it, else return default value. If to_null is
* set to true will allow null return.
*
* @param mixed $val Input variable
* @param bool|null $default Default value
* @param bool $to_null Convert to null (default no)
* @return bool|null Input var or default value
*/
protected static function setBoolMain(
mixed $val,
?bool $default = null,
bool $to_null = false
): ?bool {
if (is_bool($val)) {
return $val;
}
if ($to_null === false) {
return (bool)$default;
}
return $default;
}
/**
* Convert anything to bool. If it is a string it will try to use the filter_var
* to convert know true/false strings.
* Else it uses (bool) to convert the rest
* If null is allowed, will return null
*
* @param mixed $val Input variable
* @param bool $default Default value if to_null if false
* @param bool $to_null Convert to null (default no)
* @return bool|null Converted input data to bool/ null
*/
protected static function makeBoolMain(
mixed $val,
bool $default = false,
bool $to_null = false
): ?bool {
$boolvar = is_string($val) ?
filter_var(
$val,
FILTER_VALIDATE_BOOLEAN,
FILTER_NULL_ON_FAILURE
) :
(bool)$val;
return $boolvar === null && !$to_null ? $default : $boolvar;
}
}
// __END__

70
src/Convert/Html.php Normal file
View File

@@ -0,0 +1,70 @@
<?php
/*
* html convert functions
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Html
{
public const SELECTED = 0;
public const CHECKED = 1;
/**
* full wrapper for html entities
*
* @param mixed $string string to html encode
* @return mixed if string, encoded, else as is (eg null)
*/
public static function htmlent($string)
{
if (is_string($string)) {
return htmlentities($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
} else {
return $string;
}
}
/**
* strips out all line breaks or replaced with given string
* @param string $string string
* @param string $replace replace character, default ' '
* @return string cleaned string without any line breaks
*/
public static function removeLB(string $string, string $replace = ' '): string
{
return str_replace(["\n\r", "\r", "\n"], $replace, $string);
}
/**
* returns 'checked' or 'selected' if okay
* $needle is a var, $haystack an array or a string
* **** THE RETURN: VALUE WILL CHANGE TO A DEFAULT NULL IF NOT FOUND ****
*
* @param array<mixed>|string $haystack (search in) haystack can be
* an array or a string
* @param string $needle needle (search for)
* @param int $type type: 0: returns selected, 1,
* returns checked
* @return ?string returns checked or selected,
* else returns null
*/
public static function checked($haystack, string $needle, int $type = 0): ?string
{
if (is_array($haystack)) {
if (in_array($needle, $haystack)) {
return $type ? 'checked' : 'selected';
}
} else {
if ($haystack == $needle) {
return $type ? 'checked' : 'selected';
}
}
return null;
}
}
// __END__

97
src/Convert/Json.php Normal file
View File

@@ -0,0 +1,97 @@
<?php
/*
* Converts a json string to array and stores error for later checking
* can also return empty array on demand
* and self set json as is on error as array
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Json
{
/** @var int */
private static $json_last_error;
/**
* converts a json string to an array
* or inits an empty array on null string
* or failed convert to array
* In ANY case it will ALWAYS return array.
* Does not throw errors
*
* @param string|null $json a json string, or null data
* @param bool $override if set to true, then on json error
* set original value as array
* @return array<mixed> returns an array from the json values
*/
public static function jsonConvertToArray(?string $json, bool $override = false): array
{
if ($json !== null) {
$_json = json_decode($json, true);
if (self::$json_last_error = json_last_error()) {
if ($override == true) {
// init return as array with original as element
$json = [$json];
} else {
$json = [];
}
} else {
$json = $_json;
}
} else {
$json = [];
}
// be sure that we return an array
return (array)$json;
}
/**
* returns human readable string for json errors thrown in jsonConvertToArray
*
* @param bool|boolean $return_string [default=false] if set to true
* it will return the message string and not
* the error number
* @return int|string Either error number (0 for no error)
* or error string ('' for no error)
*/
public static function jsonGetLastError(bool $return_string = false)
{
$json_error_string = '';
// valid errors as of php 8.0
switch (self::$json_last_error) {
case JSON_ERROR_NONE:
$json_error_string = '';
break;
case JSON_ERROR_DEPTH:
$json_error_string = 'Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$json_error_string = 'Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
$json_error_string = 'Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
$json_error_string = 'Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
$json_error_string = 'Malformed UTF-8 characters, possibly incorrectly encoded';
break;
case JSON_ERROR_INVALID_PROPERTY_NAME:
$json_error_string = 'A key starting with \u0000 character was in the string';
break;
case JSON_ERROR_UTF16:
$json_error_string = 'Single unpaired UTF-16 surrogate in unicode escape';
break;
default:
$json_error_string = 'Unknown error';
break;
}
return $return_string === true ? $json_error_string : self::$json_last_error;
}
}
// __END__

61
src/Convert/Math.php Normal file
View File

@@ -0,0 +1,61 @@
<?php
/*
* various math related function wrappers
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Math
{
/**
* some float numbers will be rounded up even if they have no decimal entries
* this function fixes this by pre-rounding before calling ceil
*
* @param float $number number to round
* @param int|integer $precision intermediat round up decimals (default 10)
* @return float correct ceil number
*/
public static function fceil(float $number, int $precision = 10): float
{
return ceil(round($number, $precision));
}
/**
* round inside an a number, not the decimal part only
* eg 48767 with -2 -> 48700
*
* @param float $number number to round
* @param int $precision negative number for position in number (default -2)
* @return float rounded number
*/
public static function floorp(float $number, int $precision = -2): float
{
// if precision is requal or larger than the number length,
// set precision to length -1
if (abs($precision) >= strlen((string)$number)) {
$precision = (strlen((string)$number) - 1) * -1;
}
$mult = pow(10, $precision); // Can be cached in lookup table
return floor($number * $mult) / $mult;
}
/**
* inits input to 0, if value is not numeric
*
* @param string|int|float $number string or number to check
* @return float if not number, then returns 0, else original input
*/
public static function initNumeric($number): float
{
if (!is_numeric($number)) {
return 0;
} else {
return (float)$number;
}
}
}
// __END__

View File

@@ -0,0 +1,85 @@
<?php
/*
* Translates a mime id string into the actual application or file name
* for example 'text/plain' will output 'Text file'
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class MimeAppName
{
/** @var array<string,string> */
private static $mime_apps = [];
/**
* constructor: init mime list
*/
public function __construct()
{
self::$mime_apps = [
// zip
'application/zip' => 'Zip File',
// Powerpoint
'application/vnd.ms-powerpoint' => 'Microsoft Powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'Microsoft Powerpoint',
// PDF
'pplication/pdf' => 'PDF',
// JPEG
'image/jpeg' => 'JPEG',
// PNG
'image/png' => 'PNG',
// Indesign
'application/x-indesign' => 'Adobe InDesign',
// Photoshop
'image/vnd.adobe.photoshop' => 'Adobe Photoshop',
'application/photoshop' => 'Adobe Photoshop',
// Illustrator
'application/illustrator' => 'Adobe Illustrator',
// Word
'application/vnd.ms-word' => 'Microsoft Word',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'Microsoft Word',
// Excel
'application/vnd.ms-excel' => 'Microsoft Excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'Microsoft Excel',
// plain text
'text/plain' => 'Text file',
// html
'text/html' => 'HTML',
// mp4 (max 45MB each)
'video/mpeg' => 'MPEG Video'
];
}
/**
* Sets or updates a mime type
*
* @param string $mime MIME Name, no validiation
* @param string $app Applicaiton name
* @return void
*/
public static function mimeSetAppName(string $mime, string $app): void
{
// if empty, don't set
if (empty($mime) || empty($app)) {
return;
}
self::$mime_apps[$mime] = $app;
}
/**
* get the application name from mime type
* if not set returns "Other file"
*
* @param string $mime MIME Name
* @return string Application name matching
*/
public static function mimeGetAppName(string $mime): string
{
return self::$mime_apps[$mime] ?? 'Other file';
}
}
// __END__

View File

@@ -0,0 +1,71 @@
<?php
/*
* alternate for header mime encode to void problems with long strings and
* spaces/strange encoding problems.
* Orignal issues during PHP5/7
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class MimeEncode
{
/**
* wrapper function for mb mime convert
* for correct conversion with long strings
*
* @param string $string string to encode
* @param string $encoding target encoding
* @param string $line_break default line break is \r\n
* @return string encoded string
*/
public static function __mbMimeEncode(
string $string,
string $encoding,
string $line_break = "\r\n"
): string {
$current_internal_encoding = mb_internal_encoding();
// set internal encoding, so the mimeheader encode works correctly
mb_internal_encoding($encoding);
// if a subject, make a work around for the broken mb_mimencode
$pos = 0;
// after 36 single bytes characters,
// if then comes MB, it is broken
// has to 2 x 36 < 74 so the mb_encode_mimeheader
// 74 hardcoded split does not get triggered
$split = 36;
$_string = '';
while ($pos < mb_strlen($string, $encoding)) {
$output = mb_strimwidth($string, $pos, $split, "", $encoding);
$pos += mb_strlen($output, $encoding);
// if the strinlen is 0 here, get out of the loop
if (!mb_strlen($output, $encoding)) {
$pos += mb_strlen($string, $encoding);
}
$_string_encoded = mb_encode_mimeheader($output, $encoding);
// only make linebreaks if we have mime encoded code inside
// the space only belongs in the second line
if ($_string && preg_match("/^=\?/", $_string_encoded)) {
$_string .= $line_break . " ";
} elseif (
// hack for plain text with space at the end
mb_strlen($output, $encoding) == $split &&
mb_substr($output, -1, 1, $encoding) == " "
) {
// if output ends with space, add one more
$_string_encoded .= " ";
}
$_string .= $_string_encoded;
}
// strip out any spaces BEFORE a line break
$string = str_replace(" " . $line_break, $line_break, $_string);
// before we end, reset internal encoding
mb_internal_encoding($current_internal_encoding);
// return mime encoded string
return $string;
}
}
// __END__

123
src/Convert/Strings.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
/*
* string convert and transform functions
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
class Strings
{
/**
* return the number of elements in the split list
* 0 if nothing / invalid split
* 1 if no split character found
* n for the numbers in the split list
*
* @param string $split_format
* @param string $split_characters
* @return int
*/
public static function countSplitParts(
string $split_format,
string $split_characters = '-'
): int {
if (
empty($split_format) ||
// non valid characters inside, abort
!preg_match("/^[0-9" . $split_characters . "]/", $split_format) ||
preg_match('/[^\x20-\x7e]/', $split_characters)
) {
return 0;
}
$split_list = preg_split(
// allowed split characters
"/([" . $split_characters . "]{1})/",
$split_format
);
if (!is_array($split_list)) {
return 0;
}
return count(array_filter($split_list));
}
/**
* split format a string base on a split format string
* split format string is eg
* 4-4-4 that means 4 characters DASH 4 characters DASH 4 characters
* So a string in the format of
* ABCD1234EFGH will be ABCD-1234-EFGH
* Note a string LONGER then the maxium will be attached with the LAST
* split character. In above exmaple
* ABCD1234EFGHTOOLONG will be ABCD-1234-EFGH-TOOLONG
*
* @param string $value string value to split
* @param string $split_format split format
* @param string $split_characters list of charcters with which we split
* if not set uses dash ('-')
* @return string split formatted string or original value if not chnaged
*/
public static function splitFormatString(
string $value,
string $split_format,
string $split_characters = '-'
): string {
if (
// abort if split format is empty
empty($split_format) ||
// if not in the valid ASCII character range for any of the strings
preg_match('/[^\x20-\x7e]/', $value) ||
// preg_match('/[^\x20-\x7e]/', $split_format) ||
preg_match('/[^\x20-\x7e]/', $split_characters) ||
// only numbers and split characters in split_format
!preg_match("/[0-9" . $split_characters . "]/", $split_format)
) {
return $value;
}
// split format list
$split_list = preg_split(
// allowed split characters
"/([" . $split_characters . "]{1})/",
$split_format,
-1,
PREG_SPLIT_DELIM_CAPTURE
);
// if this is false, or only one array, abort split
if (!is_array($split_list) || count($split_list) == 1) {
return $value;
}
$out = '';
$pos = 0;
$last_split = '';
foreach ($split_list as $offset) {
if (is_numeric($offset)) {
$_part = substr($value, $pos, (int)$offset);
if (empty($_part)) {
break;
}
$out .= $_part;
$pos += (int)$offset;
} elseif ($pos) { // if first, do not add
$out .= $offset;
$last_split = $offset;
}
}
if (!empty($out) && $pos < strlen($value)) {
$out .= $last_split . substr($value, $pos);
}
// if last is not alphanumeric remove, remove
if (!strcspn(substr($out, -1, 1), $split_characters)) {
$out = substr($out, 0, -1);
}
// overwrite only if out is set
if (!empty($out)) {
return $out;
} else {
return $value;
}
}
}
// __END__

136
src/Convert/VarSetType.php Normal file
View File

@@ -0,0 +1,136 @@
<?php
/*
* Run is_<type> checks and return default value if not this type
* This will return a default value as always what is expected and never null
* Use this for santize output from multi return functions where we know what
* will come back
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Convert\Extends\VarSetTypeMain;
class VarSetType extends Extends\VarSetTypeMain
{
/**
* Check is input is string, if not return default string.
* Will always return string
*
* @param mixed $val Input value
* @param string $default Default override value
* @return string Input value or default as string
*/
public static function setStr(mixed $val, string $default = ''): string
{
return (string)VarSetTypeMain::setStrMain($val, $default, false);
}
/**
* Convert input to string if possible.
* Will only work on string/int/float/bool/null types
* Will always return string
*
* @param mixed $val Input value
* @param string $default Default override value
* @return string Input value as string or default as string
*/
public static function makeStr(mixed $val, string $default = ''): string
{
return (string)VarSetTypeMain::makeStrMain($val, $default, false);
}
/**
* Check if input is int, if not return default int value 0.
* Will always return int.
*
* @param mixed $val Input value
* @param int $default Default override value
* @return int Input value or default as int
*/
public static function setInt(mixed $val, int $default = 0): int
{
return (int)VarSetTypeMain::setIntMain($val, $default, false);
}
/**
* Convert intput to int if possible, if not return default value 0.
* Will always return int.
*
* @param mixed $val Input value
* @param int $default Default override value
* @return int Input value as int or default as int
*/
public static function makeInt(mixed $val, int $default = 0): int
{
return (int)VarSetTypeMain::makeIntMain($val, $default, false);
}
/**
* Check if input is float, if not return default value value 0.0.
* Will always return float
*
* @param mixed $val Input value
* @param float $default Default override value
* @return float Input value or default as float
*/
public static function setFloat(mixed $val, float $default = 0.0): float
{
return (float)VarSetTypeMain::setFloatMain($val, $default, false);
}
/**
* Convert input to float, if not possible return default value 0.0.
* Will always return float
*
* @param mixed $val Input value
* @param float $default Default override value
* @return float Input value as float or default as float
*/
public static function makeFloat(mixed $val, float $default = 0.0): float
{
return (float)VarSetTypeMain::makeFloatMain($val, $default, false);
}
/**
* Check if input is array, if not return default empty array.
* Will always return array.
*
* @param mixed $val Input value
* @param array<mixed> $default Default override value
* @return array<mixed> Input value or default as array
*/
public static function setArray(mixed $val, array $default = []): array
{
return (array)VarSetTypeMain::setArrayMain($val, $default, false);
}
/**
* Check if input is bool, if not will return default value false.
* Will aways return bool.
*
* @param mixed $val Input value
* @param bool $default Default override value
* @return bool Input value or default as bool
*/
public static function setBool(mixed $val, bool $default = false): bool
{
return (bool)VarSetTypeMain::setBoolMain($val, $default, false);
}
/**
* Convert anything to bool
*
* @param mixed $val Input value
* @param bool $default Default override value
* @return bool Input value as bool or default as bool
*/
public static function makeBool(mixed $val, bool $default = false): bool
{
return (bool)VarSetTypeMain::makeBoolMain($val, $default, false);
}
}
// __END__

View File

@@ -0,0 +1,130 @@
<?php
/*
* Run is_<type> checks and return default value if not this type
* This will return default null on invalid entries
*/
declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Convert\Extends\VarSetTypeMain;
class VarSetTypeNull extends Extends\VarSetTypeMain
{
/**
* Check is input is string, if not return default string.
* Will return null if no string as default.
*
* @param mixed $val Input value
* @param string|null $default Default override value
* @return string|null Input value or default as string/null
*/
public static function setStr(mixed $val, ?string $default = null): ?string
{
return VarSetTypeMain::setStrMain($val, $default, true);
}
/**
* Convert input to string if possible.
* Will only work on string/int/float/bool/null types.
* Will return null if convert failed as default.
*
* @param mixed $val Input value
* @param string|null $default Default override value
* @return string|null Input value as string or default as string/null
*/
public static function makeStr(mixed $val, string $default = null): ?string
{
return VarSetTypeMain::makeStrMain($val, $default, true);
}
/**
* Check if input is int, if not return default value null.
*
* @param mixed $val Input value
* @param int|null $default Default override value
* @return int|null Input value or default as int/null
*/
public static function setInt(mixed $val, ?int $default = null): ?int
{
return VarSetTypeMain::setIntMain($val, $default, true);
}
/**
* Convert intput to int if possible, if not return default value value null.
*
* @param mixed $val Input value $val
* @param int|null $default Default override value
* @return int|null Input value as int or default as int/null
*/
public static function makeInt(mixed $val, int $default = null): ?int
{
return VarSetTypeMain::makeIntMain($val, $default, true);
}
/**
* Check if input is float, if not return default value value null.
*
* @param mixed $val Input value $val
* @param float|null $default Default override value
* @return float|null Input value or default as float/null
*/
public static function setFloat(mixed $val, ?float $default = null): ?float
{
return VarSetTypeMain::setFloatMain($val, $default, true);
}
/**
* Convert input to float, if not possible return default value null.
*
* @param mixed $val Input value $val
* @param float|null $default Default override value
* @return float|null Input value as float or default as float/null
*/
public static function makeFloat(mixed $val, float $default = null): ?float
{
return VarSetTypeMain::makeFloatMain($val, $default, true);
}
/**
* Check if input is array, if not return default value null.
*
* @param mixed $val Input value $val
* @param array<mixed>|null $default Default override value
* @return array<mixed>|null Input value or default as array/null
*/
public static function setArray(mixed $val, ?array $default = null): ?array
{
return VarSetTypeMain::setArrayMain($val, $default, true);
}
/**
* Check if input is bool, if not will return default value null.
*
* @param mixed $val Input value $val
* @param bool|null $default Default override value
* @return bool|null Input value or default as bool/null
*/
public static function setBool(mixed $val, ?bool $default = null): ?bool
{
return VarSetTypeMain::setBoolMain($val, $default, true);
}
/**
* Convert anything to bool
*
* @param mixed $val Input value $val
* @return bool|null Input value as bool or default as bool/null
*/
public static function makeBool(mixed $val): ?bool
{
// note that the default value here is irrelevant, we return null
// on unsetable string var
return VarSetTypeMain::makeBoolMain($val, false, true);
}
}
// __END__