Fixes for CoreLibs based on phpunit tests

Add note that on change in lib/ folder (add/name/delete) 'composer
dump-autoload' must be run to update the composer auto loader as this is
currently on testing to not use internal autoloader

update all composer/vender autoload configs

Check\Basic: just apply updates in deprecated method calls
Check\Jason: has been deprecaged and moved to Convert\Json. Primary issue
was wrong name "Jason" instead of "Json"
Check\Password: only
Check\PhpVersion: fix version check for >9 numbers
Combined\Array: variable name change to be more clear, all searches are
strict for recoursive search, new option for recoursive search many to
return only found array data and no control array info. for backwards
compatible this is default set to ($old = true) and needs to be set to
false to get the new format,
array search normal has a new strict flag for forcing strict compare on
search.
remove some unneeded is_array checks,
fixed the flatten array to key to not only use leave elements, but all
array keys, if only leaves are wanted the new method
flattenArrayKeyLeavesOnly only returns key from leaves
Combined\DateTime: checkDateTime got more correct error checks on
invalid data
compareDate uses strtotimestamp for more easier compare like
compareDateTime does, both to a check on inalid timestamp now
calcDaysInterval also aborts on invalid data now
Convert\Byte: str to bytes does not drop the minus sign anymore
Convert\Colors: any error will now return false and not set to some
neutral gray. also fix missing round on hsb/hsl special return groups
Convert\Html: add constants for CHECKED/SELECTED options, fix remove
linebreak to not add two spaces if \r\n was found
Convert\Json: moved from Check\Jason and add two new error types
Convert\MimeAppName: do not set if mime type or app name is empty
Create\Hash: add crc32b to hash allows types so we can create a normal
not reversed crc32b
Create\Uids: move default hash type to var in class, fix defined
constant check
Debug\FileWriter: add log folder setting to override config constant
settings and also check if we can actually write to the folder and if
BASE and LOG constants are not empty
Get\System: add constant for getPageName and fix getHostName to be more
shorter and faster
Language\L10n: remove \Basic class extends because we don't need it
there at all
Template\SmartyExtend: fix constant check
This commit is contained in:
Clemens Schwaighofer
2022-01-13 13:20:28 +09:00
parent cb63a3eaa9
commit 13c0fcd869
23 changed files with 460 additions and 270 deletions

View File

@@ -40,8 +40,8 @@ print '<div><a href="class_test.php">Class Test Master</a></div>';
print "GETHOSTNAME: " . DgS::printAr(System::getHostName()) . "<br>";
print "GETPAGENAME(0): " . System::getPageName() . "<br>";
print "GETPAGENAME(1): " . System::getPageName(1) . "<br>";
print "GETPAGENAME(2): " . System::getPageName(2) . "<br>";
print "GETPAGENAME(1): " . System::getPageName(System::NO_EXTENSION) . "<br>";
print "GETPAGENAME(2): " . System::getPageName(System::FULL_PATH) . "<br>";
print "GETPAGENAMEARRAY: " . \CoreLibs\Debug\Support::printAr(System::getPageNameArray()) . "<br>";
// seting errro codes file upload
print "FILEUPLOADERRORMESSAGE(): " . System::fileUploadErrorMessage(-1) . "<br>";

View File

@@ -309,6 +309,7 @@ if (defined('DEBUG') && DEBUG == false) {
// "lib/"
// ]
// },
// NOTE: MUST RUN composer dump-autoload if file/class names are changed or added
// NOTE BASE: __DIR__ . DIRECTORY_SEPARATOR . '..' DIRECTORY_SEPARATOR;
require BASE . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';

View File

@@ -598,7 +598,7 @@ class Basic
public static function arraySearchRecursiveAll($needle, array $haystack, $key, ?array $path = null): ?array
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Combined\ArrayHandler::arraySearchRecursiveAll()', E_USER_DEPRECATED);
return \CoreLibs\Combined\ArrayHandler::arraySearchRecursiveAll($needle, $haystack, $key, $path);
return \CoreLibs\Combined\ArrayHandler::arraySearchRecursiveAll($needle, $haystack, $key, true, $path);
}
/**
@@ -1533,12 +1533,12 @@ class Basic
* @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
* @deprecated use \CoreLibs\Check\Jason::jsonConvertToArray() instead
* @deprecated use \CoreLibs\Check\Json::jsonConvertToArray() instead
*/
public function jsonConvertToArray(?string $json, bool $override = false): array
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Jason::jsonConvertToArray()', E_USER_DEPRECATED);
return \CoreLibs\Check\Jason::jsonConvertToArray($json, $override);
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Json::jsonConvertToArray()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Json::jsonConvertToArray($json, $override);
}
/**
@@ -1548,12 +1548,12 @@ class Basic
* the error number
* @return int|string Either error number (0 for no error)
* or error string ('' for no error)
* @deprecated use \CoreLibs\Check\Jason::jsonGetLastError() instead
* @deprecated use \CoreLibs\Check\Json::jsonGetLastError() instead
*/
public function jsonGetLastError(bool $return_string = false)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Jason::jsonGetLastError()', E_USER_DEPRECATED);
return \CoreLibs\Check\Jason::jsonGetLastError($return_string);
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Json::jsonGetLastError()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Json::jsonGetLastError($return_string);
}
// *** JSON END ***

View File

@@ -1,88 +1,41 @@
<?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
* DEPRECATED: Use correct Json:: instead
*/
declare(strict_types=1);
namespace CoreLibs\Check;
use CoreLibs\Convert\Json;
class Jason
{
/** @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
* @deprecated Use Json::jsonConvertToArray()
*/
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;
return Json::jsonConvertToArray($json, $override);
}
/**
* [jsonGetLastError description]
* @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)
* @deprecated Use Json::jsonGetLastError()
*/
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;
default:
$json_error_string = 'Unknown error';
break;
}
return $return_string === true ? $json_error_string : self::$json_last_error;
return Json::jsonGetLastError($return_string);
}
}

View File

@@ -18,7 +18,8 @@ class Password
public static function passwordSet(string $password): string
{
// always use the PHP default for the password
// password options ca be set in the password init, but should be kept as default
// password options ca be set in the password init,
// but should be kept as default
return password_hash($password, PASSWORD_DEFAULT);
}

View File

@@ -15,11 +15,11 @@ class PhpVersion
public static function checkPHPVersion(string $min_version, string $max_version = ''): bool
{
// exit with false if the min/max strings are wrong
if (!preg_match("/^\d{1}(\.\d{1})?(\.\d{1,2})?$/", $min_version)) {
if (!preg_match("/^\d{1,2}(\.\d{1,2})?(\.\d{1,2})?$/", $min_version)) {
return false;
}
// max is only chcked if it is set
if ($max_version && !preg_match("/^\d{1}(\.\d{1})?(\.\d{1,2})?$/", $max_version)) {
if ($max_version && !preg_match("/^\d{1,2}(\.\d{1,2})?(\.\d{1,2})?$/", $max_version)) {
return false;
}
// split up the version strings to calc the compare number

View File

@@ -13,38 +13,39 @@ class ArrayHandler
/**
* searches key = value in an array / array
* only returns the first one found
* @param string|int $needle needle (search for)
* @param array<mixed> $haystack haystack (search in)
* @param string|null $key_lookin the key to look out for, default empty
* @return array<mixed> array with the elements where the needle can be
* found in the haystack array
* @param string|int $needle needle (search for)
* @param array<mixed> $haystack haystack (search in)
* @param string|null $key_search_for the key to look out for, default empty
* @return array<mixed> array with the elements where
* the needle can be found in the
* haystack array
*/
public static function arraySearchRecursive($needle, array $haystack, ?string $key_lookin = null): array
public static function arraySearchRecursive($needle, array $haystack, ?string $key_search_for = null): array
{
$path = [];
if (!is_array($haystack)) {
$haystack = [];
}
if (
$key_lookin != null &&
array_key_exists($key_lookin, $haystack) &&
$needle === $haystack[$key_lookin]
$key_search_for != null &&
array_key_exists($key_search_for, $haystack) &&
$needle === $haystack[$key_search_for]
) {
$path[] = $key_lookin;
$path[] = $key_search_for;
} else {
foreach ($haystack as $key => $val) {
if (
is_scalar($val) &&
$val === $needle &&
empty($key_lookin)
empty($key_search_for)
) {
$path[] = $key;
break;
} elseif (
is_scalar($val) &&
!empty($key_lookin) &&
$key === $key_lookin &&
$val == $needle
!empty($key_search_for) &&
$key === $key_search_for &&
$val === $needle
) {
$path[] = $key;
break;
@@ -54,7 +55,7 @@ class ArrayHandler
$needle,
(array)$val,
// to avoid PhanTypeMismatchArgumentNullable
($key_lookin === null ? $key_lookin : (string)$key_lookin)
($key_search_for === null ? $key_search_for : (string)$key_search_for)
)
) {
array_unshift($path, $key);
@@ -67,14 +68,21 @@ class ArrayHandler
/**
* recursive array search function, which returns all found not only the first one
* @param string|int $needle needle (search for)
* @param array<mixed> $haystack haystack (search in)
* @param string|int $key the key to look for in
* @param array<mixed>|null $path recursive call for previous path
* @return array<mixed>|null all array elements paths where the element was found
* @param string|int $needle needle (search for)
* @param array<mixed> $haystack haystack (search in)
* @param string|int $key_search_for the key to look for in
* @param bool $old [true], if set to false will return new flat layout
* @param array<mixed>|null $path recursive call for previous path
* @return array<mixed>|null all array elements paths where
* the element was found
*/
public static function arraySearchRecursiveAll($needle, array $haystack, $key, ?array $path = null): ?array
{
public static function arraySearchRecursiveAll(
$needle,
array $haystack,
$key_search_for,
bool $old = true,
?array $path = null
): ?array {
// init if not set on null
if ($path === null) {
$path = [
@@ -97,11 +105,20 @@ class ArrayHandler
// go through the array,
foreach ($haystack as $_key => $_value) {
if (is_scalar($_value) && $_value == $needle && !$key) {
if (
is_scalar($_value) &&
$_value === $needle &&
empty($key_search_for)
) {
// only value matches
$path['work'][$path['level'] ?? 0] = $_key;
$path['found'][] = $path['work'];
} elseif (is_scalar($_value) && $_value == $needle && $_key == $key) {
} elseif (
is_scalar($_value) &&
!empty($key_search_for) &&
$_key === $key_search_for &&
$_value === $needle
) {
// key and value matches
$path['work'][$path['level'] ?? 0] = $_key;
$path['found'][] = $path['work'];
@@ -111,7 +128,7 @@ class ArrayHandler
// we will up a level
$path['level'] += 1;
// call recursive
$path = self::arraySearchRecursiveAll($needle, $_value, $key, $path);
$path = self::arraySearchRecursiveAll($needle, $_value, $key_search_for, $old, $path);
}
}
// be 100% sure the array elements are set
@@ -121,17 +138,23 @@ class ArrayHandler
array_splice($path['work'], $path['level']);
// step back a level
$path['level'] -= 1;
return $path;
if ($old === false && $path['level'] == -1) {
return $path['found'] ?? [];
} else {
return $path;
}
}
/**
* array search simple. looks for key, value combination, if found, returns true
* on default does not strict check, so string '4' will match int 4 and vica versa
* @param array<mixed> $array search in as array
* @param string|int $key key (key to search in)
* @param string|int $value value (what to find)
* @param bool $strict [false], if set to true, will strict check key/value
* @return bool true on found, false on not found
*/
public static function arraySearchSimple(array $array, $key, $value): bool
public static function arraySearchSimple(array $array, $key, $value, bool $strict = false): bool
{
if (!is_array($array)) {
$array = [];
@@ -140,10 +163,12 @@ class ArrayHandler
// if value is an array, we search
if (is_array($_value)) {
// call recursive, and return result if it is true, else continue
if (($result = self::arraySearchSimple($_value, $key, $value)) !== false) {
if (($result = self::arraySearchSimple($_value, $key, $value, $strict)) !== false) {
return $result;
}
} elseif ($_key == $key && $_value == $value) {
} elseif ($strict === false && $_key == $key && $_value == $value) {
return true;
} elseif ($strict === true && $_key === $key && $_value === $value) {
return true;
}
}
@@ -152,7 +177,8 @@ class ArrayHandler
}
/**
* correctly recursive merges as an array as array_merge_recursive just glues things together
* correctly recursive merges as an array as array_merge_recursive
* just glues things together
* array first array to merge
* array second array to merge
* ... etc
@@ -224,7 +250,8 @@ class ArrayHandler
}
/**
* search for the needle array elements in haystack and return the ones found as an array,
* search for the needle array elements in haystack and
* return the ones found as an array,
* is there nothing found, it returns FALSE (boolean)
* @param array<mixed> $needle elements to search for
* @param array<mixed> $haystack array where the $needle elements should be searched int
@@ -232,12 +259,6 @@ class ArrayHandler
*/
public static function inArrayAny(array $needle, array $haystack)
{
if (!is_array($needle)) {
return false;
}
if (!is_array($haystack)) {
return false;
}
$found = [];
foreach ($needle as $element) {
if (in_array($element, $haystack)) {
@@ -268,12 +289,20 @@ class ArrayHandler
if (
$key !== false &&
$value !== false &&
(($set_only && $db_array[$i][$value]) || (!$set_only))
(($set_only && !empty($db_array[$i][$value])) ||
(!$set_only && isset($db_array[$i][$value]))) &&
!empty($db_array[$i][$key])
) {
$ret_array[$db_array[$i][$key]] = $db_array[$i][$value];
} elseif ($key === false && $value !== false) {
} elseif (
$key === false && $value !== false &&
isset($db_array[$i][$value])
) {
$ret_array[] = $db_array[$i][$value];
} elseif ($key !== false && $value === false) {
} elseif (
$key !== false && $value === false &&
!empty($db_array[$i][$key])
) {
$ret_array[$db_array[$i][$key]] = $i;
}
}
@@ -283,7 +312,7 @@ class ArrayHandler
/**
* converts multi dimensional array to a flat array
* does NOT preserve keys
* @param array<mixed> $array ulti dimensionial array
* @param array<mixed> $array multi dimensionial array
* @return array<mixed> flattened array
*/
public static function flattenArray(array $array): array
@@ -303,7 +332,24 @@ class ArrayHandler
* @param array<mixed> $array multidemnsional array to flatten
* @return array<mixed> flattened keys array
*/
public static function flattenArrayKey(array $array): array
public static function flattenArrayKey(array $array, array $return = []): array
{
foreach ($array as $key => $sub) {
$return[] = $key;
if (is_array($sub) && count($sub) > 0) {
$return = self::flattenArrayKey($sub, $return);
}
}
return $return;
}
/**
* as above will flatten an array, but in this case only the outmost
* leave nodes, all other keyswill be skipped
* @param array<mixed> $array multidemnsional array to flatten
* @return array<mixed> flattened keys array
*/
public static function flattenArrayKeyLeavesOnly(array $array): array
{
$return = [];
array_walk_recursive(
@@ -319,7 +365,8 @@ class ArrayHandler
* searches for key -> value in an array tree and writes the value one level up
* this will remove this leaf will all other values
* @param array<mixed> $array nested array
* @param string|int $search key to find that has no sub leaf and will be pushed up
* @param string|int $search key to find that has no sub leaf
* and will be pushed up
* @return array<mixed> modified, flattened array
*/
public static function arrayFlatForKey(array $array, $search): array
@@ -329,16 +376,17 @@ class ArrayHandler
}
foreach ($array as $key => $value) {
// if it is not an array do just nothing
if (is_array($value)) {
// probe it has search key
if (isset($value[$search])) {
// set as current
$array[$key] = $value[$search];
} else {
// call up next node down
// $array[$key] = call_user_func(__METHOD__, $value, $search);
$array[$key] = self::arrayFlatForKey($value, $search);
}
if (!is_array($value)) {
continue;
}
// probe it has search key
if (isset($value[$search])) {
// set as current
$array[$key] = $value[$search];
} else {
// call up next node down
// $array[$key] = call_user_func(__METHOD__, $value, $search);
$array[$key] = self::arrayFlatForKey($value, $search);
}
}
return $array;

View File

@@ -8,10 +8,13 @@ declare(strict_types=1);
namespace CoreLibs\Combined;
use Exception;
class DateTime
{
/**
* a simple wrapper for the date format
* if an invalid timestamp is give zero timestamp unix time is used
* @param int|float $timestamp unix timestamp
* @param bool $show_micro show the micro time (default false)
* @return string formated date+time in Y-M-D h:m:s ms
@@ -85,7 +88,7 @@ class DateTime
}
/**
* does a reverse of the TimeStringFormat and converts the string from
* does a reverse of the timeStringFormat and converts the string from
* xd xh xm xs xms to a timestamp.microtime format
* @param string|int|float $timestring formatted interval
* @return string|int|float converted float interval, or string as is
@@ -159,9 +162,10 @@ class DateTime
if (!$datetime) {
return false;
}
list ($year, $month, $day, $hour, $min, $sec) = array_pad(
// catch last overflow if sec has - in front
list ($year, $month, $day, $hour, $min, $sec, $sec_overflow) = array_pad(
preg_split("/[\/\- :]/", $datetime) ?: [],
6,
7,
null
);
if (!$year || !$month || !$day) {
@@ -173,10 +177,19 @@ class DateTime
if (!is_numeric($hour) || !is_numeric($min)) {
return false;
}
if (!empty($sec) && !is_numeric($sec)) {
return false;
}
if (!empty($sec) && ($sec < 0 || $sec > 60)) {
return false;
};
// in case we have - for seconds
if (!empty($sec_overflow)) {
return false;
}
if (
($hour < 0 || $hour > 24) ||
($min < 0 || $min > 60) ||
(is_numeric($sec) && ($sec < 0 || $sec > 60))
($min < 0 || $min > 60)
) {
return false;
}
@@ -200,39 +213,23 @@ class DateTime
if ($start_date == '--' || $end_date == '--' || !$start_date || !$end_date) {
return false;
}
// splits the data up with / or -
list ($start_year, $start_month, $start_day) = array_pad(
preg_split('/[\/-]/', $start_date) ?: [],
3,
null
);
list ($end_year, $end_month, $end_day) = array_pad(
preg_split('/[\/-]/', $end_date) ?: [],
3,
null
);
// check that month & day are two digits and then combine
foreach (['start', 'end'] as $prefix) {
foreach (['month', 'day'] as $date_part) {
$_date = $prefix . '_' . $date_part;
if (isset($$_date) && $$_date < 10 && !preg_match("/^0/", $$_date)) {
$$_date = '0' . $$_date;
}
}
$_date = $prefix . '_date';
$$_date = '';
foreach (['year', 'month', 'day'] as $date_part) {
$_sub_date = $prefix . '_' . $date_part;
$$_date .= $$_sub_date;
}
// if invalid, quit
if (($start_timestamp = strtotime($start_date)) === false) {
return false;
}
// now do the compare
if ($start_date < $end_date) {
if (($end_timestamp = strtotime($end_date)) === false) {
return false;
}
// convert anything to Y-m-d and then to timestamp
// this is to remove any time parts
$start_timestamp = strtotime(date('Y-m-d', $start_timestamp));
$end_timestamp = strtotime(date('Y-m-d', $end_timestamp));
// compare, or end with false
if ($start_timestamp < $end_timestamp) {
return -1;
} elseif ($start_date == $end_date) {
} elseif ($start_timestamp == $end_timestamp) {
return 0;
} elseif ($start_date > $end_date) {
} elseif ($start_timestamp > $end_timestamp) {
return 1;
} else {
return false;
@@ -256,8 +253,14 @@ class DateTime
if ($start_datetime == '--' || $end_datetime == '--' || !$start_datetime || !$end_datetime) {
return false;
}
$start_timestamp = strtotime($start_datetime);
$end_timestamp = strtotime($end_datetime);
// quit if invalid timestamp
if (($start_timestamp = strtotime($start_datetime)) === false) {
return false;
}
if (($end_timestamp = strtotime($end_datetime)) === false) {
return false;
}
// compare, or return false
if ($start_timestamp < $end_timestamp) {
return -1;
} elseif ($start_timestamp == $end_timestamp) {
@@ -282,17 +285,29 @@ class DateTime
{
// pos 0 all, pos 1 weekday, pos 2 weekend
$days = [];
$start = new \DateTime($start_date);
$end = new \DateTime($end_date);
// if anything invalid, return 0,0,0
try {
$start = new \DateTime($start_date);
$end = new \DateTime($end_date);
} catch (Exception) {
if ($return_named === true) {
return [
'overall' => 0,
'weekday' => 0,
'weekend' => 0,
];
} else {
return [0, 0, 0];
}
}
// so we include the last day too, we need to add +1 second in the time
$end->setTime(0, 0, 1);
// if end date before start date, only this will be filled
$days[0] = $end->diff($start)->days;
$days[1] = 0;
$days[2] = 0;
// get period for weekends/weekdays
$period = new \DatePeriod($start, new \DateInterval('P1D'), $end);
foreach ($period as $dt) {
$curr = $dt->format('D');
if ($curr == 'Sat' || $curr == 'Sun') {
@@ -305,7 +320,7 @@ class DateTime
return [
'overall' => $days[0],
'weekday' => $days[1],
'weekend' => $days[2]
'weekend' => $days[2],
];
} else {
return $days;

View File

@@ -124,22 +124,26 @@ class Byte
$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",
"/(-)?([\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[1]) && isset($matches[2])) {
if (isset($matches[2]) && isset($matches[3])) {
// remove all non valid characters from the number
$number = preg_replace('/[^0-9\.]/', '', $matches[1]);
$number = preg_replace('/[^0-9\.]/', '', $matches[2]);
// final clean up and convert to float
$number = (float)trim($number);
// convert any mb/gb/etc to single m/b
$unit = preg_replace('/[^bkmgtpezy]/i', '', $matches[2]);
$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;

View File

@@ -2,8 +2,8 @@
/*
* Convert color spaces
* hex to rgb
* rgb to hex
* hex to rgb
* rgb to hsb
* hsb to rgb
* rgb to hsl
@@ -16,59 +16,27 @@ namespace CoreLibs\Convert;
class Colors
{
/**
* converts a hex RGB color to the int numbers
* @param string $hexStr RGB hexstring
* @param bool $returnAsString 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 $returnAsString = 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 $returnAsString ? implode($seperator, $rgbArray) : $rgbArray;
}
/**
* 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 rgb in hex values with leading # if set
* @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): string
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, set to gray
// if not valid, abort
if ($$color < 0 || $$color > 255) {
$$color = 125;
return false;
}
// pad left with 0
$hex_color .= str_pad(dechex($$color), 2, '0', STR_PAD_LEFT);
@@ -77,20 +45,59 @@ class Colors
}
/**
* 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> Hue, Sat, Brightness/Value
* @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): array
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) {
$$c = 0;
return false;
}
$$c = $$c / 255;
}
@@ -122,31 +129,35 @@ class Colors
}
/**
* hsb2rgb does not clean convert back to hsb in a round trip
* converts HSB/V to RGB values RGB is full INT
* @param int $H hue 0-360
* @param int $S saturation 0-100 (int)
* @param int $V brightness/value 0-100 (int)
* @return array<int> 0 red/1 green/2 blue array as 0-255
* if HSB/V value is invalid, sets this value to 0
* @param int $H hue 0-360 (int)
* @param int $S saturation 0-100 (int)
* @param int $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(int $H, int $S, int $V): array
public static function hsb2rgb(int $H, int $S, int $V)
{
// check that H is 0 to 359, 360 = 0
// and S and V are 0 to 1
if ($H < 0 || $H > 359) {
$H = 0;
return false;
}
if ($S < 0 || $S > 100) {
$S = 0;
return false;
}
if ($V < 0 || $V > 100) {
$V = 0;
return false;
}
// convert to internal 0-1 format
$S /= 100;
$V /= 100;
if ($S == 0) {
return [$V * 255, $V * 255, $V * 255];
$V = (int)round($V * 255);
return [$V, $V, $V];
}
$Hi = floor($H / 60);
@@ -203,17 +214,18 @@ class Colors
* 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> hue/sat/luminance
* @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): array
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) {
$$c = 0;
return false;
}
$$c = $$c / 255;
}
@@ -254,21 +266,25 @@ class Colors
/**
* converts an HSL to RGB
* @param int $hue hue: 0-360 (degrees)
* @param float $sat saturation: 0-100
* @param float $lum luminance: 0-100
* @return array<int,float|int> red/blue/green 0-255 each
* if HSL value is invalid, set this value to 0
* @param int|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(int $hue, float $sat, float $lum): array
public static function hsl2rgb($hue, float $sat, float $lum)
{
if (!is_numeric($hue)) {
return false;
}
if ($hue < 0 || $hue > 359) {
$hue = 0;
return false;
}
if ($sat < 0 || $sat > 100) {
$sat = 0;
return false;
}
if ($lum < 0 || $lum > 100) {
$lum = 0;
return false;
}
$hue = (1 / 360) * $hue; // calc to internal convert value for hue
// convert to internal 0-1 format
@@ -276,7 +292,8 @@ class Colors
$lum /= 100;
// if saturation is 0
if ($sat == 0) {
return [$lum * 255, $lum * 255, $lum * 255];
$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;

View File

@@ -10,6 +10,9 @@ 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
@@ -32,7 +35,7 @@ class Html
*/
public static function removeLB(string $string, string $replace = ' '): string
{
return str_replace(["\r", "\n"], $replace, $string);
return str_replace(["\n\r", "\r", "\n"], $replace, $string);
}
/**
@@ -44,10 +47,10 @@ class Html
* @param int $type type: 0: returns selected, 1, returns checked
* @return ?string returns checked or selected, else returns null
*/
public static function checked($haystack, $needle, int $type = 0): ?string
public static function checked($haystack, string $needle, int $type = 0): ?string
{
if (is_array($haystack)) {
if (in_array((string)$needle, $haystack)) {
if (in_array($needle, $haystack)) {
return $type ? 'checked' : 'selected';
}
} else {

View File

@@ -0,0 +1,95 @@
<?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__

View File

@@ -61,6 +61,10 @@ class MimeAppName
*/
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;
}

View File

@@ -15,6 +15,7 @@ class Hash
* can return empty string if none of string sets work
* hash returns false
* preg_replace fails for older php version
* Use __hash with crc32b or hash('crc32b', ...) for correct output
* @param string $string string to crc
* @return string crc32b hash (old type)
*/
@@ -52,7 +53,7 @@ class Hash
/**
* replacemend for __crc32b call (alternate)
* defaults to adler 32
* allowed adler32, fnv132, fnv1a32, joaat
* allowed crc32b, adler32, fnv132, fnv1a32, joaat
* all that create 8 char long hashes
* @param string $string string to hash
* @param string $hash_type hash type (default adler32)
@@ -60,7 +61,12 @@ class Hash
*/
public static function __hash(string $string, string $hash_type = 'adler32'): string
{
if (!in_array($hash_type, ['adler32', 'fnv132', 'fnv1a32', 'joaat'])) {
if (
!in_array(
$hash_type,
['crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat']
)
) {
$hash_type = 'adler32';
}
return hash($hash_type, $string);

View File

@@ -6,6 +6,9 @@ namespace CoreLibs\Create;
class Uids
{
// what to use as a default hash if non ise set and no DEFAULT_HASH is defined
private const FALLBACK_HASH = 'sha256';
/**
* creates psuedo random uuid v4
* Code take from class here:
@@ -54,8 +57,12 @@ class Uids
$uniq_id = hash('sha256', uniqid((string)rand(), true));
break;
default:
$hash = 'sha256';
if (defined(DEFAULT_HASH)) {
// fallback to this hash type
$hash = self::FALLBACK_HASH;
if (
defined('DEFAULT_HASH') && !empty(DEFAULT_HASH) &&
in_array(DEFAULT_HASH, hash_algos())
) {
$hash = DEFAULT_HASH;
}
$uniq_id = hash($hash, uniqid((string)rand(), true));

View File

@@ -9,7 +9,7 @@
*
* pgsql wrapper calls
*
* HISTORY:
* HISTORY:
* 2008/04/16 (cs) wrapper for pg escape string
* 2007/01/11 (cs) add prepare/execute for postgres
* 2006/09/12 (cs) in case db_query retuns false, save the query and
@@ -21,10 +21,9 @@
* 2005/07/07 (cs) the default it is table_name _ id
* 2005/01/19 (cs) changed the pgsql connect, so it dies if it can't connect to the DB
* 2004/09/30 (cs) layout cleanup
* /
*
*
* collection of PostgreSQL wrappers
* REQUIRES 5.x PHP!!!
*
* pg_prepare
* pg_execute

View File

@@ -13,6 +13,31 @@ class FileWriter
{
/** @var string */
private static $debug_filename = 'debug_file.log'; // where to write output
private static $debug_folder;
/**
* Set a debug log folder, if not set BASE+LOG folders are set
* if they are defined
* This folder name must exist and must be writeable
*
* @param string $folder Folder name to where the log file will be written
* @return boolean True for valid folder name, False for invalid
*/
public static function fsetFolder(string $folder): bool
{
if (!preg_match("/^[\w\-\/]+/", $folder)) {
return false;
}
if (!is_writeable($folder)) {
return false;
}
// if last is not / then add
if (substr($folder, -1, 1) != DIRECTORY_SEPARATOR) {
$folder .= DIRECTORY_SEPARATOR;
}
self::$debug_folder = $folder;
return true;
}
/**
* set new debug file name
@@ -25,7 +50,7 @@ class FileWriter
public static function fsetFilename(string $filename): bool
{
// valid file. must be only ascii & _, must end with .log
if (!preg_match("/^[A-Za-z_-]+\.log$/", $filename)) {
if (!preg_match("/^[\w\-]+\.log$/", $filename)) {
return false;
}
self::$debug_filename = $filename;
@@ -40,13 +65,21 @@ class FileWriter
*/
public static function fdebug(string $string, bool $enter = true): bool
{
if (!self::$debug_filename) {
if (empty(self::$debug_filename)) {
return false;
}
if (!is_writeable(BASE . LOG)) {
// if empty try to set base log folder
if (
empty(self::$debug_folder) &&
defined('BASE') && !empty(BASE) &&
defined('LOG') && !empty(LOG)
) {
self::$debug_folder = BASE . LOG;
}
if (!is_writeable(self::$debug_folder)) {
return false;
}
$filename = BASE . LOG . self::$debug_filename;
$filename = self::$debug_folder . self::$debug_filename;
$fh = fopen($filename, 'a');
if ($fh === false) {
return false;

View File

@@ -31,7 +31,7 @@ class RunningTime
* first call sets start time and returns 0,
* second call sets end time and returns the run time
* the out_time parameter can be:
* n/ns (nano), y/ys (micro), m/ms (milli), s
* n/ns (nano), y/ys (micro), m/ms (milli), s (seconds)
* default is milliseconds
* @param string $out_time set return time adjustment calculation
* @return float running time without out_time suffix

View File

@@ -10,7 +10,12 @@ namespace CoreLibs\Get;
class System
{
/**
public const WITH_EXTENSION = 0;
public const NO_EXTENSION = 1;
public const FULL_PATH = 2;
private const DEFAULT_PORT = '80';
/**
* helper function for PHP file upload error messgaes to messge string
* @param int $error_code integer _FILE upload error code
* @return string message string, translated
@@ -52,33 +57,30 @@ class System
*/
public static function getHostName(): array
{
$port = '';
if ($_SERVER['HTTP_HOST'] && preg_match("/:/", $_SERVER['HTTP_HOST'])) {
list($host_name, $port) = explode(":", $_SERVER['HTTP_HOST']);
} elseif ($_SERVER['HTTP_HOST']) {
$host_name = $_SERVER['HTTP_HOST'];
} else {
$host_name = 'NA';
}
return [$host_name, ($port ? $port : 80)];
$host = $_SERVER['HTTP_HOST'] ?? 'NOHOST:NOPORT';
list($host_name, $port) = array_pad(explode(':', $host), 2, self::DEFAULT_PORT);
return [$host_name, $port];
}
/**
* get the page name of the curronte page
* @param int $strip_ext 1: strip page file name extension
* 0: keep filename as is
* 2: keep filename as is, but add dirname too
* @param int $strip_ext WITH_EXTENSION: keep filename as is (default)
* NO_EXTENSION: strip page file name extension
* FULL_PATH: keep filename as is, but add dirname too
* @return string filename
*/
public static function getPageName(int $strip_ext = 0): string
public static function getPageName(int $strip_ext = self::WITH_EXTENSION): string
{
// get the file info
$page_temp = pathinfo($_SERVER['PHP_SELF']);
if ($strip_ext == 1) {
if ($strip_ext == self::NO_EXTENSION) {
// no extension
return $page_temp['filename'];
} elseif ($strip_ext == 2) {
} elseif ($strip_ext == self::FULL_PATH) {
// full path
return $_SERVER['PHP_SELF'];
} else {
// with extension
return $page_temp['basename'];
}
}

View File

@@ -31,7 +31,7 @@ namespace CoreLibs\Language;
use CoreLibs\Language\Core\FileReader;
use CoreLibs\Language\Core\GetTextReader;
class L10n extends \CoreLibs\Basic
class L10n
{
/** @var string */
private $lang = '';
@@ -49,7 +49,7 @@ class L10n extends \CoreLibs\Basic
*/
public function __construct(string $lang = '', string $path = '')
{
parent::__construct();
// parent::__construct();
if (!$lang) {
$this->lang = 'en';
} else {

View File

@@ -467,7 +467,7 @@ class SmartyExtend extends SmartyBC
// set local page title
$this->HEADER['HTML_TITLE'] = !$this->L_TITLE ?
ucfirst(str_replace('_', ' ', \CoreLibs\Get\System::getPageName(1)))
. (defined(G_TITLE) ? ' - ' . $this->l10n->__(G_TITLE) : '') :
. (defined('G_TITLE') ? ' - ' . $this->l10n->__(G_TITLE) : '') :
$this->l10n->__($this->L_TITLE);
// LANG

View File

@@ -21,6 +21,7 @@ return array(
'CoreLibs\\Convert\\Byte' => $baseDir . '/lib/CoreLibs/Convert/Byte.php',
'CoreLibs\\Convert\\Colors' => $baseDir . '/lib/CoreLibs/Convert/Colors.php',
'CoreLibs\\Convert\\Html' => $baseDir . '/lib/CoreLibs/Convert/Html.php',
'CoreLibs\\Convert\\Json' => $baseDir . '/lib/CoreLibs/Convert/Json.php',
'CoreLibs\\Convert\\Math' => $baseDir . '/lib/CoreLibs/Convert/Math.php',
'CoreLibs\\Convert\\MimeAppName' => $baseDir . '/lib/CoreLibs/Convert/MimeAppName.php',
'CoreLibs\\Create\\Hash' => $baseDir . '/lib/CoreLibs/Create/Hash.php',

View File

@@ -86,6 +86,7 @@ class ComposerStaticInit10fe8fe2ec4017b8644d2b64bcf398b9
'CoreLibs\\Convert\\Byte' => __DIR__ . '/../..' . '/lib/CoreLibs/Convert/Byte.php',
'CoreLibs\\Convert\\Colors' => __DIR__ . '/../..' . '/lib/CoreLibs/Convert/Colors.php',
'CoreLibs\\Convert\\Html' => __DIR__ . '/../..' . '/lib/CoreLibs/Convert/Html.php',
'CoreLibs\\Convert\\Json' => __DIR__ . '/../..' . '/lib/CoreLibs/Convert/Json.php',
'CoreLibs\\Convert\\Math' => __DIR__ . '/../..' . '/lib/CoreLibs/Convert/Math.php',
'CoreLibs\\Convert\\MimeAppName' => __DIR__ . '/../..' . '/lib/CoreLibs/Convert/MimeAppName.php',
'CoreLibs\\Create\\Hash' => __DIR__ . '/../..' . '/lib/CoreLibs/Create/Hash.php',