diff --git a/www/admin/class_test.system.php b/www/admin/class_test.system.php index 7c126d48..82adf93c 100644 --- a/www/admin/class_test.system.php +++ b/www/admin/class_test.system.php @@ -40,8 +40,8 @@ print '
Class Test Master
'; print "GETHOSTNAME: " . DgS::printAr(System::getHostName()) . "
"; print "GETPAGENAME(0): " . System::getPageName() . "
"; -print "GETPAGENAME(1): " . System::getPageName(1) . "
"; -print "GETPAGENAME(2): " . System::getPageName(2) . "
"; +print "GETPAGENAME(1): " . System::getPageName(System::NO_EXTENSION) . "
"; +print "GETPAGENAME(2): " . System::getPageName(System::FULL_PATH) . "
"; print "GETPAGENAMEARRAY: " . \CoreLibs\Debug\Support::printAr(System::getPageNameArray()) . "
"; // seting errro codes file upload print "FILEUPLOADERRORMESSAGE(): " . System::fileUploadErrorMessage(-1) . "
"; diff --git a/www/configs/config.master.php b/www/configs/config.master.php index da6d4eee..c8efc3ee 100644 --- a/www/configs/config.master.php +++ b/www/configs/config.master.php @@ -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'; diff --git a/www/lib/CoreLibs/Basic.php b/www/lib/CoreLibs/Basic.php index 464097a4..be83677a 100644 --- a/www/lib/CoreLibs/Basic.php +++ b/www/lib/CoreLibs/Basic.php @@ -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 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 *** diff --git a/www/lib/CoreLibs/Check/Jason.php b/www/lib/CoreLibs/Check/Jason.php index c40e8bc8..821a2381 100644 --- a/www/lib/CoreLibs/Check/Jason.php +++ b/www/lib/CoreLibs/Check/Jason.php @@ -1,88 +1,41 @@ 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); } } diff --git a/www/lib/CoreLibs/Check/Password.php b/www/lib/CoreLibs/Check/Password.php index 610231e6..a77eddc0 100644 --- a/www/lib/CoreLibs/Check/Password.php +++ b/www/lib/CoreLibs/Check/Password.php @@ -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); } diff --git a/www/lib/CoreLibs/Check/PhpVersion.php b/www/lib/CoreLibs/Check/PhpVersion.php index 8f906b6c..2f70abdc 100644 --- a/www/lib/CoreLibs/Check/PhpVersion.php +++ b/www/lib/CoreLibs/Check/PhpVersion.php @@ -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 diff --git a/www/lib/CoreLibs/Combined/ArrayHandler.php b/www/lib/CoreLibs/Combined/ArrayHandler.php index 87029bf7..a970385d 100644 --- a/www/lib/CoreLibs/Combined/ArrayHandler.php +++ b/www/lib/CoreLibs/Combined/ArrayHandler.php @@ -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 $haystack haystack (search in) - * @param string|null $key_lookin the key to look out for, default empty - * @return array array with the elements where the needle can be - * found in the haystack array + * @param string|int $needle needle (search for) + * @param array $haystack haystack (search in) + * @param string|null $key_search_for the key to look out for, default empty + * @return array 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 $haystack haystack (search in) - * @param string|int $key the key to look for in - * @param array|null $path recursive call for previous path - * @return array|null all array elements paths where the element was found + * @param string|int $needle needle (search for) + * @param array $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|null $path recursive call for previous path + * @return array|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 $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 $needle elements to search for * @param array $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 $array ulti dimensionial array + * @param array $array multi dimensionial array * @return array flattened array */ public static function flattenArray(array $array): array @@ -303,7 +332,24 @@ class ArrayHandler * @param array $array multidemnsional array to flatten * @return array 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 $array multidemnsional array to flatten + * @return array 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 $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 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; diff --git a/www/lib/CoreLibs/Combined/DateTime.php b/www/lib/CoreLibs/Combined/DateTime.php index 61b29a53..ec0838b1 100644 --- a/www/lib/CoreLibs/Combined/DateTime.php +++ b/www/lib/CoreLibs/Combined/DateTime.php @@ -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; diff --git a/www/lib/CoreLibs/Convert/Byte.php b/www/lib/CoreLibs/Convert/Byte.php index a80620f8..cb2f056b 100644 --- a/www/lib/CoreLibs/Convert/Byte.php +++ b/www/lib/CoreLibs/Convert/Byte.php @@ -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; diff --git a/www/lib/CoreLibs/Convert/Colors.php b/www/lib/CoreLibs/Convert/Colors.php index bcc5d801..f565ebda 100644 --- a/www/lib/CoreLibs/Convert/Colors.php +++ b/www/lib/CoreLibs/Convert/Colors.php @@ -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|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|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 Hue, Sat, Brightness/Value + * @param int $red red 0-255 + * @param int $green green 0-255 + * @param int $blue blue 0-255 + * @return array|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 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|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 hue/sat/luminance + * @param int $red red 0-255 + * @param int $green green 0-255 + * @param int $blue blue 0-255 + * @return array|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 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|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; diff --git a/www/lib/CoreLibs/Convert/Html.php b/www/lib/CoreLibs/Convert/Html.php index 39b15724..24a52896 100644 --- a/www/lib/CoreLibs/Convert/Html.php +++ b/www/lib/CoreLibs/Convert/Html.php @@ -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 { diff --git a/www/lib/CoreLibs/Convert/Json.php b/www/lib/CoreLibs/Convert/Json.php new file mode 100644 index 00000000..1771d650 --- /dev/null +++ b/www/lib/CoreLibs/Convert/Json.php @@ -0,0 +1,95 @@ + 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__ diff --git a/www/lib/CoreLibs/Convert/MimeAppName.php b/www/lib/CoreLibs/Convert/MimeAppName.php index 2368d759..2726e56d 100644 --- a/www/lib/CoreLibs/Convert/MimeAppName.php +++ b/www/lib/CoreLibs/Convert/MimeAppName.php @@ -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; } diff --git a/www/lib/CoreLibs/Create/Hash.php b/www/lib/CoreLibs/Create/Hash.php index 9b6d81ed..c9f13f56 100644 --- a/www/lib/CoreLibs/Create/Hash.php +++ b/www/lib/CoreLibs/Create/Hash.php @@ -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); diff --git a/www/lib/CoreLibs/Create/Uids.php b/www/lib/CoreLibs/Create/Uids.php index 6b02438e..baf023f2 100644 --- a/www/lib/CoreLibs/Create/Uids.php +++ b/www/lib/CoreLibs/Create/Uids.php @@ -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)); diff --git a/www/lib/CoreLibs/DB/SQL/PgSQL.php b/www/lib/CoreLibs/DB/SQL/PgSQL.php index dabce935..8f4589ff 100644 --- a/www/lib/CoreLibs/DB/SQL/PgSQL.php +++ b/www/lib/CoreLibs/DB/SQL/PgSQL.php @@ -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 diff --git a/www/lib/CoreLibs/Debug/FileWriter.php b/www/lib/CoreLibs/Debug/FileWriter.php index f5abf363..1436efc5 100644 --- a/www/lib/CoreLibs/Debug/FileWriter.php +++ b/www/lib/CoreLibs/Debug/FileWriter.php @@ -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; diff --git a/www/lib/CoreLibs/Debug/RunningTime.php b/www/lib/CoreLibs/Debug/RunningTime.php index f4bed22a..6e95478c 100644 --- a/www/lib/CoreLibs/Debug/RunningTime.php +++ b/www/lib/CoreLibs/Debug/RunningTime.php @@ -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 diff --git a/www/lib/CoreLibs/Get/System.php b/www/lib/CoreLibs/Get/System.php index 5d9cf87f..878cbbba 100644 --- a/www/lib/CoreLibs/Get/System.php +++ b/www/lib/CoreLibs/Get/System.php @@ -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']; } } diff --git a/www/lib/CoreLibs/Language/L10n.php b/www/lib/CoreLibs/Language/L10n.php index 5526616d..300a6787 100644 --- a/www/lib/CoreLibs/Language/L10n.php +++ b/www/lib/CoreLibs/Language/L10n.php @@ -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 { diff --git a/www/lib/CoreLibs/Template/SmartyExtend.php b/www/lib/CoreLibs/Template/SmartyExtend.php index 4192076e..e8223245 100644 --- a/www/lib/CoreLibs/Template/SmartyExtend.php +++ b/www/lib/CoreLibs/Template/SmartyExtend.php @@ -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 diff --git a/www/vendor/composer/autoload_classmap.php b/www/vendor/composer/autoload_classmap.php index 319574e1..52545be2 100644 --- a/www/vendor/composer/autoload_classmap.php +++ b/www/vendor/composer/autoload_classmap.php @@ -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', diff --git a/www/vendor/composer/autoload_static.php b/www/vendor/composer/autoload_static.php index d1a31f77..1f79a8dc 100644 --- a/www/vendor/composer/autoload_static.php +++ b/www/vendor/composer/autoload_static.php @@ -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',