Merge branch 'development' into feature/TTD-2608/LoginACLSetAjaxPageViaClassOption

This commit is contained in:
Clemens Schwaighofer
2025-06-05 18:26:08 +09:00
32 changed files with 4348 additions and 320 deletions

View File

@@ -383,7 +383,8 @@ class Basic
public function initRandomKeyLength(int $key_length): bool
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\RandomKey::setRandomKeyLength()', E_USER_DEPRECATED);
return \CoreLibs\Create\RandomKey::setRandomKeyLength($key_length);
// no op, we do no longer pre set the random key length
return true;
}
/**
@@ -988,10 +989,10 @@ class Basic
* @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
* @return string|false encoding converted string
* @deprecated use \CoreLibs\Convert\Encoding::convertEncoding() instead
*/
public static function convertEncoding(string $string, string $to_encoding, string $source_encoding = '', bool $auto_check = true): string
public static function convertEncoding(string $string, string $to_encoding, string $source_encoding = '', bool $auto_check = true): string|false
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Encoding::convertEncoding()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Encoding::convertEncoding($string, $to_encoding, $source_encoding, $auto_check);

View File

@@ -56,7 +56,11 @@ class Encoding
{
// return mb_substitute_character();
if ($return_substitute_func === true) {
return mb_substitute_character();
// if false abort with error
if (($return = mb_substitute_character()) === false) {
return self::$mb_error_char;
}
return $return;
} else {
return self::$mb_error_char;
}
@@ -88,7 +92,13 @@ class Encoding
): array|false {
// convert to target encoding and convert back
$temp = mb_convert_encoding($string, $to_encoding, $from_encoding);
if ($temp === false) {
return false;
}
$compare = mb_convert_encoding($temp, $from_encoding, $to_encoding);
if ($compare === false) {
return false;
}
// if string does not match anymore we have a convert problem
if ($string == $compare) {
return false;

View File

@@ -10,6 +10,8 @@ namespace CoreLibs\Combined;
class ArrayHandler
{
public const string DATA_SEPARATOR = ':';
/**
* searches key = value in an array / array
* only returns the first one found
@@ -148,18 +150,22 @@ class ArrayHandler
* 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|bool $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
* @param array<mixed> $array search in as array
* @param string|int $key key (key to search in)
* @param string|int|bool|array<string|int|bool> $value values list (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,
string|int $key,
string|int|bool $value,
string|int|bool|array $value,
bool $strict = false
): bool {
// convert to array
if (!is_array($value)) {
$value = [$value];
}
foreach ($array as $_key => $_value) {
// if value is an array, we search
if (is_array($_value)) {
@@ -167,9 +173,9 @@ class ArrayHandler
if (($result = self::arraySearchSimple($_value, $key, $value, $strict)) !== false) {
return $result;
}
} elseif ($strict === false && $_key == $key && $_value == $value) {
} elseif ($strict === false && $_key == $key && in_array($_value, $value)) {
return true;
} elseif ($strict === true && $_key === $key && $_value === $value) {
} elseif ($strict === true && $_key === $key && in_array($_value, $value, true)) {
return true;
}
}
@@ -236,6 +242,160 @@ class ArrayHandler
return $hit_list;
}
/**
* Search in an array for value with or without key and
* check in the same array block for the required key
* If not found return an array with the array block there the required key is missing,
* the path as string with seperator block set and the missing key entry
*
* @param array<mixed> $array
* @param string|int|float|bool $search_value
* @param string|array<string> $required_key
* @param ?string $search_key [null]
* @param string $path_separator [DATA_SEPARATOR]
* @param string $current_path
* @return array<array{content?:array<mixed>,path?:string,missing_key?:array<string>}>
*/
public static function findArraysMissingKey(
array $array,
string|int|float|bool $search_value,
string|array $required_key,
?string $search_key = null,
string $path_separator = self::DATA_SEPARATOR,
string $current_path = ''
): array {
$results = [];
foreach ($array as $key => $value) {
$path = $current_path ? $current_path . $path_separator . $key : $key;
if (is_array($value)) {
// Check if this array contains the search value
// either any value match or with key
if ($search_key === null) {
$containsValue = in_array($search_value, $value, true);
} else {
$containsValue = array_key_exists($search_key, $value) && $value[$search_key] === $search_value;
}
// If it contains the value but doesn't have the required key
if (
$containsValue &&
(
(
is_string($required_key) &&
!array_key_exists($required_key, $value)
) || (
is_array($required_key) &&
count(array_intersect($required_key, array_keys($value))) !== count($required_key)
)
)
) {
$results[] = [
'content' => $value,
'path' => $path,
'missing_key' => is_array($required_key) ?
array_values(array_diff($required_key, array_keys($value))) :
[$required_key]
];
}
// Recursively search nested arrays
$results = array_merge(
$results,
self::findArraysMissingKey(
$value,
$search_value,
$required_key,
$search_key,
$path_separator,
$path
)
);
}
}
return $results;
}
/**
* Find key => value entry and return set with key for all matching
* Can search recursively through nested arrays if recursive flag is set
*
* @param array<mixed> $array
* @param string $lookup
* @param int|string|float|bool $search
* @param bool $strict [false]
* @param bool $case_insensitive [false]
* @param bool $recursive [false]
* @param bool $flat_result [true] If set to false and recursive is on the result is a nested array
* @param string $flat_separator [DATA_SEPARATOR] if flat result is true, can be any string
* @return array<mixed>
*/
public static function selectArrayFromOption(
array $array,
string $lookup,
int|string|float|bool $search,
bool $strict = false,
bool $case_insensitive = false,
bool $recursive = false,
bool $flat_result = true,
string $flat_separator = self::DATA_SEPARATOR
): array {
// skip on empty
if ($array == []) {
return [];
}
// init return result
$result = [];
// case sensitive convert if string
if ($case_insensitive && is_string($search)) {
$search = strtolower($search);
}
foreach ($array as $key => $value) {
// Handle current level search
if (isset($value[$lookup])) {
$compareValue = $value[$lookup];
if ($case_insensitive && is_string($compareValue)) {
$compareValue = strtolower($compareValue);
}
if (
($strict && $search === $compareValue) ||
(!$strict && $search == $compareValue)
) {
$result[$key] = $value;
}
}
// Handle recursive search if flag is set
if ($recursive && is_array($value)) {
$recursiveResults = self::selectArrayFromOption(
$value,
$lookup,
$search,
$strict,
$case_insensitive,
true,
$flat_result,
$flat_separator
);
// Merge recursive results with current results
// Preserve keys by using array_merge with string keys or + operator
foreach ($recursiveResults as $recKey => $recValue) {
if ($flat_result) {
$result[$key . $flat_separator . $recKey] = $recValue;
} else {
$result[$key][$recKey] = $recValue;
}
}
}
}
return $result;
}
/**
* main wrapper function for next/prev key
*
@@ -553,12 +713,13 @@ class ArrayHandler
}
/**
* Modifieds the key of an array with a prefix and/or suffix and returns it with the original value
* Modifieds the key of an array with a prefix and/or suffix and
* returns it with the original value
* does not change order in array
*
* @param array<string|int,mixed> $in_array
* @param string $key_mod_prefix [default=''] key prefix string
* @param string $key_mod_suffix [default=''] key suffix string
* @param string $key_mod_prefix [''] key prefix string
* @param string $key_mod_suffix [''] key suffix string
* @return array<string|int,mixed>
*/
public static function arrayModifyKey(
@@ -581,6 +742,72 @@ class ArrayHandler
array_values($in_array)
);
}
/**
* sort array and return in same call
* sort ascending or descending with or without lower case convert
* value only, will loose key connections unless preserve_keys is set to true
*
* @param array<mixed> $array array to sort by values
* @param int $params sort flags
* @return array<mixed>
*/
public static function sortArray(
array $array,
bool $case_insensitive = false,
bool $reverse = false,
bool $maintain_keys = false,
int $params = SORT_REGULAR
): array {
$fk_sort_lower_case = function (string $a, string $b): int {
return strtolower($a) <=> strtolower($b);
};
$fk_sort_lower_case_reverse = function (string $a, string $b): int {
return strtolower($b) <=> strtolower($a);
};
$case_insensitive ? (
$maintain_keys ?
(uasort($array, $reverse ? $fk_sort_lower_case_reverse : $fk_sort_lower_case)) :
(usort($array, $reverse ? $fk_sort_lower_case_reverse : $fk_sort_lower_case))
) :
(
$maintain_keys ?
($reverse ? arsort($array, $params) : asort($array, $params)) :
($reverse ? rsort($array, $params) : sort($array, $params))
);
return $array;
}
/**
* sort by key ascending or descending and return
*
* @param array<mixed> $array
* @param bool $case_insensitive [false]
* @param bool $reverse [false]
* @return array<mixed>
*/
public static function ksortArray(array $array, bool $case_insensitive = false, bool $reverse = false): array
{
$fk_sort_lower_case = function (string $a, string $b): int {
return strtolower($a) <=> strtolower($b);
};
$fk_sort_lower_case_reverse = function (string $a, string $b): int {
return strtolower($b) <=> strtolower($a);
};
$fk_sort = function (string $a, string $b): int {
return $a <=> $b;
};
$fk_sort_reverse = function (string $a, string $b): int {
return $b <=> $a;
};
uksort(
$array,
$case_insensitive ?
($reverse ? $fk_sort_lower_case_reverse : $fk_sort_lower_case) :
($reverse ? $fk_sort_reverse : $fk_sort)
);
return $array;
}
}
// __END__

View File

@@ -23,14 +23,14 @@ class Encoding
* @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
* @return string|false encoding converted string or false on error
*/
public static function convertEncoding(
string $string,
string $to_encoding,
string $source_encoding = '',
bool $auto_check = true
): string {
): string|false {
// set if not given
if (!$source_encoding) {
$source_encoding = mb_detect_encoding($string);

View File

@@ -119,6 +119,23 @@ class Json
}
return $return_string === true ? $json_error_string : self::$json_last_error;
}
/**
* wrapper to call convert array to json with pretty print
*
* @param array<mixed> $data
* @return string
*/
public static function jsonPrettyPrint(array $data): string
{
return self::jsonConvertArrayTo(
$data,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_LINE_TERMINATORS |
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE
);
}
}
// __END__

View File

@@ -8,8 +8,20 @@ declare(strict_types=1);
namespace CoreLibs\Convert;
use CoreLibs\Combined\ArrayHandler;
class Strings
{
/** @var array<int,string> all the preg error messages */
public const array PREG_ERROR_MESSAGES = [
PREG_NO_ERROR => 'No error',
PREG_INTERNAL_ERROR => 'Internal PCRE error',
PREG_BACKTRACK_LIMIT_ERROR => 'Backtrack limit exhausted',
PREG_RECURSION_LIMIT_ERROR => 'Recursion limit exhausted',
PREG_BAD_UTF8_ERROR => 'Malformed UTF-8 data',
PREG_BAD_UTF8_OFFSET_ERROR => 'Bad UTF-8 offset',
PREG_JIT_STACKLIMIT_ERROR => 'JIT stack limit exhausted'
];
/**
* return the number of elements in the split list
* 0 if nothing / invalid split
@@ -52,29 +64,42 @@ class Strings
* 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
* If the characters are NOT ASCII it will return the string as is
*
* @param string $value string value to split
* @param string $string 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
* @throws \InvalidArgumentException for empty split format, invalid values, split characters or split format
*/
public static function splitFormatString(
string $value,
string $string,
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;
// skip if string or split format is empty is empty
if (empty($string) || empty($split_format)) {
return $string;
}
if (preg_match('/[^\x20-\x7e]/', $string)) {
throw new \InvalidArgumentException(
"The string to split can only be ascii characters: " . $string
);
}
// get the split characters that are not numerical and check they are ascii
$split_characters = self::removeDuplicates(preg_replace('/[0-9]/', '', $split_format) ?: '');
if (empty($split_characters)) {
throw new \InvalidArgumentException(
"A split character must exist in the format string: " . $split_format
);
}
if (preg_match('/[^\x20-\x7e]/', $split_characters)) {
throw new \InvalidArgumentException(
"The split character has to be a valid ascii character: " . $split_characters
);
}
if (!preg_match("/^[0-9" . $split_characters . "]+$/", $split_format)) {
throw new \InvalidArgumentException(
"The split format can only be numbers and the split characters: " . $split_format
);
}
// split format list
$split_list = preg_split(
@@ -86,14 +111,14 @@ class Strings
);
// if this is false, or only one array, abort split
if (!is_array($split_list) || count($split_list) == 1) {
return $value;
return $string;
}
$out = '';
$pos = 0;
$last_split = '';
foreach ($split_list as $offset) {
if (is_numeric($offset)) {
$_part = substr($value, $pos, (int)$offset);
$_part = substr($string, $pos, (int)$offset);
if (empty($_part)) {
break;
}
@@ -104,8 +129,8 @@ class Strings
$last_split = $offset;
}
}
if (!empty($out) && $pos < strlen($value)) {
$out .= $last_split . substr($value, $pos);
if (!empty($out) && $pos < strlen($string)) {
$out .= $last_split . substr($string, $pos);
}
// if last is not alphanumeric remove, remove
if (!strcspn(substr($out, -1, 1), $split_characters)) {
@@ -115,10 +140,49 @@ class Strings
if (!empty($out)) {
return $out;
} else {
return $value;
return $string;
}
}
/**
* Split a string into n-length blocks with a split character inbetween
* This is simplified version from splitFormatString that uses
* fixed split length with a characters, this evenly splits the string out into the
* given length
* This works with non ASCII characters too
*
* @param string $string string to split
* @param int $split_length split length, must be smaller than string and larger than 0
* @param string $split_characters [default=-] the character to split, can be more than one
* @return string
* @throws \InvalidArgumentException Thrown if split length style is invalid
*/
public static function splitFormatStringFixed(
string $string,
int $split_length,
string $split_characters = '-'
): string {
// if empty string or if split lenght is 0 or empty split characters
// then we skip any splitting
if (empty($string) || $split_length == 0 || empty($split_characters)) {
return $string;
}
$return_string = '';
$string_length = mb_strlen($string);
// check that the length is not too short
if ($split_length < 1 || $split_length >= $string_length) {
throw new \InvalidArgumentException(
"The split length must be at least 1 character and less than the string length to split. "
. "Split length: " . $split_length . ", string length: " . $string_length
);
}
for ($i = 0; $i < $string_length; $i += $split_length) {
$return_string .= mb_substr($string, $i, $split_length) . $split_characters;
}
// remove last trailing character which is always the split char length
return mb_substr($return_string, 0, -1 * mb_strlen($split_characters));
}
/**
* Strip any duplicated slahes from a path
* eg: //foo///bar/foo.inc -> /foo/bar/foo.inc
@@ -146,6 +210,116 @@ class Strings
{
return trim($text, pack('H*', 'EFBBBF'));
}
/**
* Make as string of characters unique
*
* @param string $string
* @return string
*/
public static function removeDuplicates(string $string): string
{
// combine again
$result = implode(
'',
// unique list
array_unique(
// split into array
mb_str_split($string)
)
);
return $result;
}
/**
* check if all characters are in set
*
* @param string $needle Needle to search
* @param string $haystack Haystack to search in
* @return bool True on found, False if not in haystack
*/
public static function allCharsInSet(string $needle, string $haystack): bool
{
$input_length = strlen($needle);
for ($i = 0; $i < $input_length; $i++) {
if (strpos($haystack, $needle[$i]) === false) {
return false;
}
}
return true;
}
/**
* converts a list of arrays of strings into a string of unique entries
* input arrays can be nested, only values are used
*
* @param array<mixed> ...$char_lists
* @return string
*/
public static function buildCharStringFromLists(array ...$char_lists): string
{
return implode('', array_unique(
ArrayHandler::flattenArray(
array_merge(...$char_lists)
)
));
}
/**
* Check if a regex is valid. Does not return the detail regex parser error
*
* @param string $pattern Any regex string
* @return bool False on invalid regex
*/
public static function isValidRegex(string $pattern): bool
{
preg_last_error();
try {
$var = '';
@preg_match($pattern, $var);
return preg_last_error() === PREG_NO_ERROR;
} catch (\Error $e) {
return false;
}
}
/**
* Returns the last preg error messages as string
* all messages are defined in PREG_ERROR_MESSAGES
*
* @return string
*/
public static function getLastRegexErrorString(): string
{
return self::PREG_ERROR_MESSAGES[preg_last_error()] ?? 'Unknown error';
}
/**
* check if a regex is invalid, returns array with flag and error string
*
* @param string $pattern
* @return array{valid:bool,preg_error:int,error:null|string,pcre_error:null|string}
*/
public static function validateRegex(string $pattern): array
{
// Clear any previous PCRE errors
preg_last_error();
$var = '';
if (@preg_match($pattern, $var) === false) {
$error = preg_last_error();
return [
'valid' => false,
'preg_error' => $error,
'error' => self::PREG_ERROR_MESSAGES[$error] ?? 'Unknown error',
'pcre_error' => preg_last_error_msg(),
];
}
return ['valid' => true, 'preg_error' => PREG_NO_ERROR, 'error' => null, 'pcre_error' => null];
}
}
// __END__

View File

@@ -38,6 +38,7 @@ class Email
* @param string $encoding Encoding, if not set UTF-8
* @param bool $kv_folding If set to true and a valid encoding, do KV folding
* @return string Correctly encoded and build email string
* @throws \IntlException if email name cannot be converted to UTF-8
*/
public static function encodeEmailName(
string $email,
@@ -52,6 +53,10 @@ class Email
if ($encoding != 'UTF-8') {
$email_name = mb_convert_encoding($email_name, $encoding, 'UTF-8');
}
// if we cannot transcode the name, return just the email
if ($email_name === false) {
throw new \IntlException('Cannot convert email_name to UTF-8');
}
$email_name =
mb_encode_mimeheader(
in_array($encoding, self::$encoding_kv_allowed) && $kv_folding ?
@@ -77,6 +82,8 @@ class Email
* @param bool $kv_folding If set to true and a valid encoding,
* do KV folding
* @return array<string> Pos 0: Subject, Pos 1: Body
* @throws \IntlException if subject cannot be converted to UTF-8
* @throws \IntlException if body cannot be converted to UTF-8
*/
private static function replaceContent(
string $subject,
@@ -102,6 +109,12 @@ class Email
$subject = mb_convert_encoding($subject, $encoding, 'UTF-8');
$body = mb_convert_encoding($body, $encoding, 'UTF-8');
}
if ($subject === false) {
throw new \IntlException('Cannot convert subject to UTF-8');
}
if ($body === false) {
throw new \IntlException('Cannot convert body to UTF-8');
}
// we need to encodde the subject
$subject = mb_encode_mimeheader(
in_array($encoding, self::$encoding_kv_allowed) && $kv_folding ?

View File

@@ -8,39 +8,97 @@ declare(strict_types=1);
namespace CoreLibs\Create;
use CoreLibs\Convert\Strings;
class RandomKey
{
/** @var int set the default key length it nothing else is set */
public const int KEY_LENGTH_DEFAULT = 4;
/** @var int the maximum key length allowed */
public const int KEY_LENGTH_MAX = 256;
/** @var string the default characters in the key range */
public const string KEY_CHARACTER_RANGE_DEFAULT =
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
. 'abcdefghijklmnopqrstuvwxyz'
. '0123456789';
// key generation
/** @var string */
private static string $key_range = '';
/** @var int */
private static int $one_key_length;
/** @var int */
private static int $key_length = 4; // default key length
/** @var int */
private static int $max_key_length = 256; // max allowed length
/** @var string all the characters that are int he current radnom key range */
private static string $key_character_range = '';
/** @var int character count in they key character range */
private static int $key_character_range_length = 0;
/** @var int default key lenghth */
/** @deprecated Will be removed */
private static int $key_length = 4;
/**
* if launched as class, init random key data first
*
* @param array<string> ...$key_range
*/
public function __construct()
public function __construct(array ...$key_range)
{
$this->initRandomKeyData();
$this->setRandomKeyData(...$key_range);
}
/**
* internal key range validation
*
* @param array<string> ...$key_range
* @return string
*/
private static function validateRandomKeyData(array ...$key_range): string
{
$key_character_range = Strings::buildCharStringFromLists(...$key_range);
if (strlen(self::$key_character_range) <= 1) {
return '';
}
return $key_character_range;
}
/**
* sets the random key range with the default values
*
* @param array<string> $key_range a list of key ranges as array
* @return void has no return
* @throws \LengthException If the string length is only 1 abort
*/
private static function initRandomKeyData(): void
public static function setRandomKeyData(array ...$key_range): void
{
// random key generation base string
self::$key_range = join('', array_merge(
range('A', 'Z'),
range('a', 'z'),
range('0', '9')
));
self::$one_key_length = strlen(self::$key_range);
// if key range is not set
if (!count($key_range)) {
self::$key_character_range = self::KEY_CHARACTER_RANGE_DEFAULT;
} else {
self::$key_character_range = self::validateRandomKeyData(...$key_range);
// random key generation base string
}
self::$key_character_range_length = strlen(self::$key_character_range);
if (self::$key_character_range_length <= 1) {
throw new \LengthException(
"The given key character range '" . self::$key_character_range . "' "
. "is too small, must be at lest two characters: "
. self::$key_character_range_length
);
}
}
/**
* get the characters for the current key characters
*
* @return string
*/
public static function getRandomKeyData(): string
{
return self::$key_character_range;
}
/**
* get the length of all random characters
*
* @return int
*/
public static function getRandomKeyDataLength(): int
{
return self::$key_character_range_length;
}
/**
@@ -53,7 +111,7 @@ class RandomKey
{
if (
$key_length > 0 &&
$key_length <= self::$max_key_length
$key_length <= self::KEY_LENGTH_MAX
) {
return true;
} else {
@@ -67,6 +125,7 @@ class RandomKey
*
* @param int $key_length key length
* @return bool true/false for set status
* @deprecated This function does no longer set the key length, the randomKeyGen parameter has to b used
*/
public static function setRandomKeyLength(int $key_length): bool
{
@@ -83,6 +142,7 @@ class RandomKey
* get the current set random key length
*
* @return int Current set key length
* @deprecated Key length is set during randomKeyGen call, this nethid is deprecated
*/
public static function getRandomKeyLength(): int
{
@@ -94,28 +154,37 @@ class RandomKey
* if override key length is set, it will check on valid key and use this
* this will not set the class key length variable
*
* @param int $key_length key length override, -1 for use default
* @return string random key
* @param int $key_length [default=-1] key length override,
* if not set use default [LEGACY]
* @param array<string> $key_range a list of key ranges as array,
* if not set use previous set data
* @return string random key
*/
public static function randomKeyGen(int $key_length = -1): string
{
// init random key strings if not set
if (
!isset(self::$one_key_length)
) {
self::initRandomKeyData();
}
$use_key_length = 0;
// only if valid int key with valid length
if (self::validateRandomKeyLenght($key_length) === true) {
$use_key_length = $key_length;
public static function randomKeyGen(
int $key_length = self::KEY_LENGTH_DEFAULT,
array ...$key_range
): string {
$key_character_range = '';
if (count($key_range)) {
$key_character_range = self::validateRandomKeyData(...$key_range);
$key_character_range_length = strlen($key_character_range);
} else {
$use_key_length = self::$key_length;
if (!self::$key_character_range_length) {
self::setRandomKeyData();
}
$key_character_range = self::getRandomKeyData();
$key_character_range_length = self::getRandomKeyDataLength();
}
// if not valid key length, fallback to default
if (!self::validateRandomKeyLenght($key_length)) {
$key_length = self::KEY_LENGTH_DEFAULT;
}
// create random string
$random_string = '';
for ($i = 1; $i <= $use_key_length; $i++) {
$random_string .= self::$key_range[random_int(0, self::$one_key_length - 1)];
for ($i = 1; $i <= $key_length; $i++) {
$random_string .= $key_character_range[
random_int(0, $key_character_range_length - 1)
];
}
return $random_string;
}

View File

@@ -35,6 +35,7 @@ class Logging
/** @var string log file block separator, not changeable */
private const LOG_FILE_BLOCK_SEPARATOR = '.';
// MARK: OPTION array
// NOTE: the second party array{} hs some errors
/** @var array<string,array<string,string|bool|Level>>|array{string:array{type:string,type_info?:string,mandatory:true,alias?:string,default:string|bool|Level,deprecated:bool,use?:string}} */
private const OPTIONS = [
@@ -50,6 +51,7 @@ class Logging
'type' => 'string', 'mandatory' => false,
'default' => '', 'deprecated' => true, 'use' => 'log_file_id'
],
// log level
'log_level' => [
'type' => 'instance',
'type_info' => '\CoreLibs\Logging\Logger\Level',
@@ -57,6 +59,14 @@ class Logging
'default' => Level::Debug,
'deprecated' => false
],
// level to trigger write to error_log
'error_log_write_level' => [
'type' => 'instance',
'type_info' => '\CoreLibs\Logging\Logger\Level',
'mandatory' => false,
'default' => Level::Emergency,
'deprecated' => false,
],
// options
'log_per_run' => [
'type' => 'bool', 'mandatory' => false,
@@ -92,8 +102,10 @@ class Logging
/** @var array<mixed> */
private array $options = [];
/** @var Level set level */
/** @var Level set logging level */
private Level $log_level;
/** @var Level set level for writing to error_log, will not write if log level lower than error log write level */
private Level $error_log_write_level;
// page and host name
/** @var string */
@@ -145,12 +157,13 @@ class Logging
];
/**
* Init logger
* MARK: Init logger
*
* options array layout
* - log_folder:
* - log_file_id / file_id (will be deprecated):
* - log_level:
* - error_log_write_level: at what level we write to error_log
*
* - log_per_run:
* - log_per_date: (was print_file_date)
@@ -172,6 +185,8 @@ class Logging
// set log level
$this->initLogLevel();
// set error log write level
$this->initErrorLogWriteLevel();
// set log folder from options
$this->initLogFolder();
// set per run UID for logging
@@ -190,8 +205,10 @@ class Logging
// PRIVATE METHODS
// *********************************************************************
// MARK: options check
/**
* Undocumented function
* validate options
*
* @param array<mixed> $options
* @return bool
@@ -263,6 +280,8 @@ class Logging
return true;
}
// MARK: init log elvels
/**
* init log level, just a wrapper to auto set from options
*
@@ -280,6 +299,24 @@ class Logging
$this->setLoggingLevel($this->options['log_level']);
}
/**
* init error log write level
*
* @return void
*/
private function initErrorLogWriteLevel()
{
if (
empty($this->options['error_log_write_level']) ||
!$this->options['error_log_write_level'] instanceof Level
) {
$this->options['error_log_write_level'] = Level::Emergency;
}
$this->setErrorLogWriteLevel($this->options['error_log_write_level']);
}
// MARK: set log folder
/**
* Set the log folder
* If folder is not writeable the script will throw an E_USER_ERROR
@@ -321,6 +358,8 @@ class Logging
return $status;
}
// MARK: set host name
/**
* Set the hostname and port
* If port is not defaul 80 it will be added to the host name
@@ -337,6 +376,8 @@ class Logging
}
}
// MARK: set log file id (file)
/**
* set log file prefix id
*
@@ -395,6 +436,8 @@ class Logging
return $status;
}
// MARK init log flags and levels
/**
* set flags from options and option flags connection internal settings
*
@@ -423,6 +466,19 @@ class Logging
return $this->log_level->includes($level);
}
/**
* Checks that given level is matchins error_log write level
*
* @param Level $level
* @return bool
*/
private function checkErrorLogWriteLevel(Level $level): bool
{
return $this->error_log_write_level->includes($level);
}
// MARK: build log ifle name
/**
* Build the file name for writing
*
@@ -490,6 +546,8 @@ class Logging
return $fn;
}
// MARK: master write log to file
/**
* writes error msg data to file for current level
*
@@ -507,6 +565,10 @@ class Logging
if (!$this->checkLogLevel($level)) {
return false;
}
// if we match level then write to error_log
if ($this->checkErrorLogWriteLevel($level)) {
error_log((string)$message);
}
// build logging file name
// fn is log folder + file name
@@ -531,6 +593,8 @@ class Logging
return true;
}
// MARK: master prepare log
/**
* Prepare the log message with all needed info blocks:
* [timestamp] [host name] [file path + file::row number] [running uid] {class::/->method}
@@ -610,6 +674,7 @@ class Logging
// PUBLIC STATIC METHJODS
// *********************************************************************
// MARK: set log level
/**
* set the log level
*
@@ -670,7 +735,7 @@ class Logging
// **** GET/SETTER
// log level set and get
// MARK: log level
/**
* set new log level
@@ -705,7 +770,30 @@ class Logging
);
}
// log file id set (file name prefix)
// MARK: error log write level
/**
* set the error_log write level
*
* @param string|int|Level $level
* @return void
*/
public function setErrorLogWriteLevel(string|int|Level $level): void
{
$this->error_log_write_level = $this->processLogLevel($level);
}
/**
* get the current level for error_log write
*
* @return Level
*/
public function getErrorLogWriteLevel(): Level
{
return $this->error_log_write_level;
}
// MARK: log file id set (file name prefix)
/**
* sets the internal log file prefix id
@@ -733,7 +821,7 @@ class Logging
return $this->log_file_id;
}
// log unique id set (for per run)
// MARK: log unique id set (for per run)
/**
* Sets a unique id based on current date (y/m/d, h:i:s) and a unique id (8 chars)
@@ -768,7 +856,7 @@ class Logging
return $this->log_file_unique_id;
}
// general log date
// MARK: general log date
/**
* set the log file date to Y-m-d
@@ -791,7 +879,7 @@ class Logging
return $this->log_file_date;
}
// general flag set
// MARK: general flag set
/**
* set one of the basic flags
@@ -846,7 +934,7 @@ class Logging
return $this->log_flags;
}
// log folder/file
// MARK: log folder/file
/**
* set new log folder, check that folder is writeable
@@ -890,7 +978,7 @@ class Logging
return $this->log_file_name;
}
// max log file size
// MARK: max log file size
/**
* set mag log file size
@@ -921,7 +1009,7 @@ class Logging
}
// *********************************************************************
// OPTIONS CALLS
// MARK: OPTIONS CALLS
// *********************************************************************
/**
@@ -939,6 +1027,8 @@ class Logging
// MAIN CALLS
// *********************************************************************
// MARK: main log call
/**
* Commong log interface
*
@@ -976,7 +1066,7 @@ class Logging
}
/**
* DEBUG: 100
* MARK: DEBUG: 100
*
* write debug data to error_msg array
*
@@ -1008,7 +1098,7 @@ class Logging
}
/**
* INFO: 200
* MARK: INFO: 200
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1027,7 +1117,7 @@ class Logging
}
/**
* NOTICE: 250
* MARK: NOTICE: 250
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1046,7 +1136,7 @@ class Logging
}
/**
* WARNING: 300
* MARK: WARNING: 300
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1065,7 +1155,7 @@ class Logging
}
/**
* ERROR: 400
* MARK: ERROR: 400
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1084,7 +1174,7 @@ class Logging
}
/**
* CTRITICAL: 500
* MARK: CTRITICAL: 500
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1103,7 +1193,7 @@ class Logging
}
/**
* ALERT: 550
* MARK: ALERT: 550
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1122,7 +1212,7 @@ class Logging
}
/**
* EMERGENCY: 600
* MARK: EMERGENCY: 600
*
* @param string|Stringable $message
* @param mixed[] $context
@@ -1141,7 +1231,7 @@ class Logging
}
// *********************************************************************
// DEPRECATED SUPPORT CALLS
// MARK: DEPRECATED SUPPORT CALLS
// *********************************************************************
// legacy, but there are too many implemented
@@ -1199,7 +1289,7 @@ class Logging
}
// *********************************************************************
// DEPRECATED METHODS
// MARK: DEPRECATED METHODS
// *********************************************************************
/**
@@ -1365,7 +1455,7 @@ class Logging
}
// *********************************************************************
// DEBUG METHODS
// MARK: DEBUG METHODS
// *********************************************************************
/**
@@ -1398,6 +1488,7 @@ class Logging
}
// back to options level
$this->initLogLevel();
$this->initErrorLogWriteLevel();
print "OPT set level: " . $this->getLoggingLevel()->getName() . "<br>";
}
}

View File

@@ -599,7 +599,7 @@ class Curl implements Interface\RequestsInterface
// for post we set POST option
if ($type == "post") {
curl_setopt($handle, CURLOPT_POST, true);
} elseif (!empty($type) && in_array($type, self::CUSTOM_REQUESTS)) {
} elseif (in_array($type, self::CUSTOM_REQUESTS)) {
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, strtoupper($type));
}
// set body data if not null, will send empty [] for empty data