From e90387c1fcdaefce6602461076ded2fe7d31c361 Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Thu, 15 May 2025 15:35:13 +0900 Subject: [PATCH] Composer update --- .gitignore | 1 + www/admin/class_test.array.php | 2 + www/admin/class_test.datetime.php | 58 +++-- .../class_test.db.convert-placeholder.php | 55 +++- www/admin/class_test.db.encryption.php | 166 +++++++++++++ www/admin/class_test.db.php | 51 ++-- www/admin/class_test.db.query-placeholder.php | 4 +- www/admin/class_test.deprecated.helper.php | 107 ++++++++ www/admin/class_test.hash.php | 63 ++++- www/admin/class_test.login.php | 24 +- www/admin/class_test.php | 2 + www/admin/class_test.phpv.php | 2 - www/admin/class_test.session.php | 2 + www/composer.lock | 4 +- www/vendor/composer/installed.json | 4 +- www/vendor/composer/installed.php | 2 +- .../corelibs-composer-all/composer.json | 2 +- .../egrajp/corelibs-composer-all/phpstan.neon | 3 + .../publish/last.published | 2 +- .../corelibs-composer-all/src/ACL/Login.php | 87 ++++++- .../src/Admin/Backend.php | 2 +- .../src/Admin/EditBase.php | 2 +- .../corelibs-composer-all/src/Basic.php | 18 +- .../src/Combined/ArrayHandler.php | 30 +++ .../src/Combined/DateTime.php | 112 ++++++++- .../src/Convert/Html.php | 24 +- .../corelibs-composer-all/src/Create/Hash.php | 139 ++++++++++- .../src/DB/Extended/ArrayIO.php | 10 +- .../corelibs-composer-all/src/DB/IO.php | 123 +++++++-- .../src/DB/SQL/Interface/SqlFunctions.php | 4 +- .../src/DB/SQL/PgSQL.php | 10 +- .../src/DB/Support/ConvertPlaceholder.php | 201 +++++++-------- .../src/Language/GetLocale.php | 4 +- .../src/Logging/Logging.php | 44 ++-- .../src/Output/Form/Generate.php | 4 +- .../src/Output/Form/TableArrays/EditUsers.php | 4 +- .../src/Output/ProgressBar.php | 4 +- .../test/configs/config.master.php | 10 +- .../test/phpunit/ACL/CoreLibsACLLoginTest.php | 9 +- .../CoreLibsCombinedArrayHandlerTest.php | 112 +++++++++ .../Combined/CoreLibsCombinedDateTimeTest.php | 207 +++++++++++++--- .../Convert/CoreLibsConvertByteTest.php | 2 +- .../phpunit/Create/CoreLibsCreateHashTest.php | 234 +++++++++++++++++- .../test/phpunit/DB/CoreLibsDBIOTest.php | 179 ++++++++++++-- .../Logging/CoreLibsLoggingLoggingTest.php | 8 +- 45 files changed, 1769 insertions(+), 368 deletions(-) create mode 100644 www/admin/class_test.db.encryption.php create mode 100644 www/admin/class_test.deprecated.helper.php diff --git a/.gitignore b/.gitignore index d8a7996a..a90ee1eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ composer.lock vendor/ +.env diff --git a/www/admin/class_test.array.php b/www/admin/class_test.array.php index 6491ee59..2e826f4d 100644 --- a/www/admin/class_test.array.php +++ b/www/admin/class_test.array.php @@ -263,6 +263,8 @@ $out = array_intersect_key( ); print "array intersect key: " . DgS::printAr($keys) . ": " . DgS::printAr($out) . "
"; +print "array + suffix: " . DgS::printAr(ArrayHandler::arrayModifyKey($array, key_mod_suffix:'_attached')) . "
"; + print ""; // __END__ diff --git a/www/admin/class_test.datetime.php b/www/admin/class_test.datetime.php index e0374599..54633004 100644 --- a/www/admin/class_test.datetime.php +++ b/www/admin/class_test.datetime.php @@ -268,7 +268,9 @@ foreach ($compare_datetimes as $compare_datetime) { print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: " . (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "
"; } + print "
"; +print "

calcDaysInterval

"; $compare_dates = [ [ '2021-05-01', '2021-05-10', ], [ '2021-05-10', '2021-05-01', ], @@ -279,9 +281,21 @@ foreach ($compare_dates as $compare_date) { print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: " . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "
"; print "CALCDAYSINTERVAL(named): $compare_date[0] = $compare_date[1]: " - . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], true)) . "
"; + . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], return_named:true)) . "
"; + print "CALCDAYSINTERVAL(EXCLUDE END): $compare_date[0] = $compare_date[1]: " + . Dgs::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], include_end_date:false)); + print "CALCDAYSINTERVAL(EXCLUDE START): $compare_date[0] = $compare_date[1]: " + . Dgs::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], exclude_start_date:true)); + print "CALCDAYSINTERVAL(EXCLUDE END, EXCLUDE START): $compare_date[0] = $compare_date[1]: " + . Dgs::printAr(DateTime::calcDaysInterval( + $compare_date[0], + $compare_date[1], + include_end_date:false, + exclude_start_date:true + )); } print "
"; +print "

setWeekdayNameFromIsoDow

"; // test date conversion $dow = 2; print "DOW[$dow]: " . DateTime::setWeekdayNameFromIsoDow($dow) . "
"; @@ -297,26 +311,25 @@ $date = '2022-70-242'; print "DATE-dow[$date];invalid: " . DateTime::setWeekdayNameFromDate($date) . "
"; print "DATE-dow[$date],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "
"; print "DOW-date[$date];invalid: " . DateTime::setWeekdayNumberFromDate($date) . "
"; -print "
"; -// check date range includes a weekend -// does not: -$start_date = '2023-07-03'; -$end_date = '2023-07-05'; -print "Has Weekend: " . $start_date . " ~ " . $end_date . ": " - . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "
"; -$start_date = '2023-07-03'; -$end_date = '2023-07-10'; -print "Has Weekend: " . $start_date . " ~ " . $end_date . ": " - . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "
"; -$start_date = '2023-07-03'; -$end_date = '2023-07-31'; -print "Has Weekend: " . $start_date . " ~ " . $end_date . ": " - . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "
"; -$start_date = '2023-07-01'; -$end_date = '2023-07-03'; -print "Has Weekend: " . $start_date . " ~ " . $end_date . ": " - . Dgs::prBl(DateTime::dateRangeHasWeekend($start_date, $end_date)) . "
"; +print "
"; +print "

dateRangeHasWeekend

"; +// check date range includes a weekend +$has_weekend_list = [ + ['2023-07-03', '2023-07-05'], + ['2023-07-03', '2023-07-10'], + ['2023-07-03', '2023-07-31'], + ['2023-07-01', '2023-07-03'], + ['2023-07-01', '2023-07-01'], + ['2023-07-01', '2023-07-02'], + ['2023-06-30', '2023-07-01'], + ['2023-06-30', '2023-06-30'], + ['2023-07-01', '2023-06-30'], +]; +foreach ($has_weekend_list as $days) { + print "Has Weekend: " . $days[0] . " ~ " . $days[1] . ": " + . Dgs::prBl(DateTime::dateRangeHasWeekend($days[0], $days[1])) . "
"; +} print ""; @@ -460,7 +473,10 @@ function intervalStringFormatDeprecated( // print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value) // . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "
"; // var_dump($skip_last_zero); - if ($value != 0 || $skip_zero === false || $skip_last_zero === false) { + if ( + is_numeric($value) && + ($value != 0 || $skip_zero === false || $skip_last_zero === false) + ) { if ($part == 'f') { if ($truncate_nanoseconds === true) { $value = round($value, 3); diff --git a/www/admin/class_test.db.convert-placeholder.php b/www/admin/class_test.db.convert-placeholder.php index 6504326f..8257805c 100644 --- a/www/admin/class_test.db.convert-placeholder.php +++ b/www/admin/class_test.db.convert-placeholder.php @@ -21,6 +21,7 @@ ob_end_flush(); use CoreLibs\Debug\Support; use CoreLibs\DB\Support\ConvertPlaceholder; +use CoreLibs\Convert\Html; $log = new CoreLibs\Logging\Logging([ 'log_folder' => BASE . LOG, @@ -38,10 +39,12 @@ print '

' . $PAGE_NAME . '

'; print "LOGFILE NAME: " . $log->getLogFile() . "
"; print "LOGFILE ID: " . $log->getLogFileId() . "
"; -print "Lookup Regex:
" . ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS . "
"; -print "Replace Named Regex:
" . ConvertPlaceholder::REGEX_REPLACE_NAMED . "
"; -print "Replace Named Regex:
" . ConvertPlaceholder::REGEX_REPLACE_QUESTION_MARK . "
"; -print "Replace Named Regex:
" . ConvertPlaceholder::REGEX_REPLACE_NUMBERED . "
"; +print "Lookup Regex:
" . Html::htmlent(ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS) . "
"; +print "Lookup Numbered Regex:
" . Html::htmlent(ConvertPlaceholder::REGEX_LOOKUP_NUMBERED) . "
"; +print "Replace Named Regex:
" . Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_NAMED) . "
"; +print "Replace Question Mark Regex:
"
+	. Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_QUESTION_MARK) . "
"; +print "Replace Numbered Regex:
" . Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_NUMBERED) . "
"; $uniqid = \CoreLibs\Create\Uids::uniqIdShort(); // $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: ''); @@ -91,40 +94,63 @@ RETURNING some_binary SQL; -print "[ALL] Convert: " +print "[ALL] Convert: " . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) . "
"; echo "
"; $query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez"; $params = [':baz' => 'SETBAZ', ':bez' => 'SETBEZ', ':biz' => 'SETBIZ']; -print "[NO PARAMS] Convert: " +print "[NO PARAMS] Convert: " . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) . "
"; echo "
"; $query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez"; $params = null; -print "[NO PARAMS] Convert: " +print "[NO PARAMS] Convert: " . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) . "
"; echo "
"; $query = "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> :row_varchar"; $params = null; -print "[NO PARAMS] Convert: " +print "[NO PARAMS] Convert: " . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) . "
"; echo "
"; $query = "SELECT row_varchar, row_varchar_literal, row_int, row_date FROM table_with_primary_key"; $params = null; -print "[NO PARAMS] TEST: " +print "[NO PARAMS] TEST: " . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) . "
"; echo "
"; -print "[P-CONV]: " +$query = <<[All the same params] TEST: " + . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) + . "
"; +echo "
"; + +$query = << 1]; +print "[: param] TEST: " + . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params)) + . "
"; +echo "
"; + +print "[P-CONV]: " . Support::printAr( ConvertPlaceholder::updateParamList([ 'original' => [ @@ -186,6 +212,13 @@ SQL, 'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234], 'direction' => 'pg', ], + 'b?' => [ + 'query' => << [1234], + 'direction' => 'pg', + ], 'b:' => [ 'query' => << $data) { $query = $data['query']; $params = $data['params']; $direction = $data['direction']; - print "[$info] Convert: " + print "[$info] Convert: " . Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params, $direction)) . "
"; echo "
"; diff --git a/www/admin/class_test.db.encryption.php b/www/admin/class_test.db.encryption.php new file mode 100644 index 00000000..6b5c6ed7 --- /dev/null +++ b/www/admin/class_test.db.encryption.php @@ -0,0 +1,166 @@ + BASE . LOG, + 'log_file_id' => $LOG_FILE_ID, + 'log_per_date' => true, +]); +// db connection and attach logger +$db = new CoreLibs\DB\IO(DB_CONFIG, $log); +$db->log->debug('START', '=============================>'); + +$PAGE_NAME = 'TEST CLASS: DB QUERY ENCRYPTION'; +print ""; +print "" . $PAGE_NAME . ""; +print ""; +print ''; +print '

' . $PAGE_NAME . '

'; + +// encryption key +$key_new = CreateKey::generateRandomKey(); +print "Secret Key NEW: " . $key_new . "
"; +// for reproducable test results +$key = 'e475c19b9a3c8363feb06b51f5b73f1dc9b6f20757d4ab89509bf5cc70ed30ec'; +print "Secret Key: " . $key . "
"; + +// test text +$text_string = "I a some deep secret"; +$text_string = "I a some deep secret ABC"; +// +$crypt = new SymmetricEncryption($key); +$encrypted = $crypt->encrypt($text_string); +$string_hashed = Hash::hashStd($text_string); +$string_hmac = Hash::hashHmac($text_string, $key); +$decrypted = $crypt->decrypt($encrypted); + +print "String: " . $text_string . "
"; +print "Encrypted: " . $encrypted . "
"; +print "Hashed: " . $string_hashed . "
"; +print "Hmac: " . $string_hmac . "
"; + +$db->dbExecParams( + <<dbGetReturningExt('cuuid'); +print "INSERTED: " . print_r($cuuid, true) . "
"; +print "LAST ERROR: " . $db->dbGetLastError(true) . "
"; + +// read back +$res = $db->dbReturnRowParams( + <<" . Support::prAr($res) . "
"; + +if ($res === false) { + echo "Failed to run query
"; +} else { + if (hash_equals($string_hashed, $res['pg_digest_text'])) { + print "libsodium and pgcrypto hash match
"; + } + if (hash_equals($string_hmac, $res['pg_hmac_text'])) { + print "libsodium and pgcrypto hash hmac match
"; + } + // do compare for PHP and pgcrypto settings + $encryptedMessage_template = <<getLiteralData()->getData(); + print "Pg decrypted PHP: " . $decrypted . "
"; + if ($decrypted == $text_string) { + print "Decryption worked
"; + } + } catch (\Exception $e) { + print "Error decrypting message: " . $e->getMessage() . "
"; + } +} + +print ""; + +// __END__ diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php index eb9ba2e6..4a7676e7 100644 --- a/www/admin/class_test.db.php +++ b/www/admin/class_test.db.php @@ -76,41 +76,41 @@ $db->dbResetEncoding(); // empty calls, none of the below should fail // -$db->dbGetCursor(); +$foo = $db->dbGetCursor(); // -$db->dbGetCursorExt(); +$foo = $db->dbGetCursorExt(); // -$db->dbGetCursorPos('SELECT foo', ['bar']); +$foo = $db->dbGetCursorPos('SELECT foo', ['bar']); // -$db->dbGetCursorNumRows('SELECT foo', ['bar']); +$foo = $db->dbGetCursorNumRows('SELECT foo', ['bar']); // -$db->dbGetInsertPKName(); +$foo = $db->dbGetInsertPKName(); // -$db->dbGetInsertPK(); +$foo = $db->dbGetInsertPK(); // -$db->dbGetReturningExt(); -$db->dbGetReturningExt('foo'); -$db->dbGetReturningExt('foo', 0); -$db->dbGetReturningExt(pos:0); +$foo = $db->dbGetReturningExt(); +$foo = $db->dbGetReturningExt('foo'); +$foo = $db->dbGetReturningExt('foo', 0); +$foo = $db->dbGetReturningExt(pos:0); // -$db->dbGetReturningArray(); +$foo = $db->dbGetReturningArray(); // -$db->dbGetNumRows(); +$foo = $db->dbGetNumRows(); // -$db->dbGetNumFields(); +$foo = $db->dbGetNumFields(); // -$db->dbGetFieldNames(); +$foo = $db->dbGetFieldNames(); // -$db->dbGetFieldTypes(); +$foo = $db->dbGetFieldTypes(); // -$db->dbGetFieldNameTypes(); +$foo = $db->dbGetFieldNameTypes(); // -$db->dbGetFieldName(0); +$foo = $db->dbGetFieldName(0); // -$db->dbGetFieldType(0); -$db->dbGetFieldType('foo'); +$foo = $db->dbGetFieldType(0); +$foo = $db->dbGetFieldType('foo'); // -$db->dbGetPrepareCursorValue('foo', 'bar'); +$foo = $db->dbGetPrepareCursorValue('foo', 'bar'); // TEST CACHE READS @@ -707,6 +707,17 @@ if ( } else { print "[PGB] [3] pgb_sel_test_foo prepare OK
"; } +$stm_status = $db->dbPreparedCursorStatus(''); +print "[PGB] Empty statement name: " . $log->prAr($stm_status) . "
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foobar'); +print "[PGB] Prepared name not match status: $stm_status
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo'); +print "[PGB] Prepared name match status: $stm_status
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', $q_prep); +print "[PGB] prepared exists and query match status: $stm_status
"; +$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', "SELECT * FROM test_foo"); +print "[PGB] prepared exists and query not match status: $stm_status
"; + $db_pgb->dbClose(); # db write class test diff --git a/www/admin/class_test.db.query-placeholder.php b/www/admin/class_test.db.query-placeholder.php index c77cff6a..0516ed05 100644 --- a/www/admin/class_test.db.query-placeholder.php +++ b/www/admin/class_test.db.query-placeholder.php @@ -54,7 +54,7 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) { print "NO DB HANDLER
"; } // REGEX for placeholder count -print "Placeholder regex:
" . CoreLibs\DB\Support\ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS . "
"; +print "Placeholder lookup regex:
" . CoreLibs\DB\Support\ConvertPlaceholder::REGEX_LOOKUP_NUMBERED . "
"; // turn on debug replace for placeholders $db->dbSetDebugReplacePlaceholder(true); @@ -148,6 +148,7 @@ RETURNING bigint_a, number_real, number_double, numeric_3, uuid_var SQL; +print "Placeholders:
" . print_r($db->dbGetQueryParamPlaceholders($query_insert), true) . "
";
 $status = $db->dbExecParams($query_insert, $query_params);
 echo "*
"; echo "INSERT ALL COLUMN TYPES: " @@ -326,6 +327,7 @@ SQL, ) { print "RES: " . Support::prAr($res) . "
"; } +print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "
"; print "ERROR: " . $db->dbGetLastError(true) . "
"; print ""; diff --git a/www/admin/class_test.deprecated.helper.php b/www/admin/class_test.deprecated.helper.php new file mode 100644 index 00000000..b629ff05 --- /dev/null +++ b/www/admin/class_test.deprecated.helper.php @@ -0,0 +1,107 @@ + BASE . LOG, + 'log_file_id' => $LOG_FILE_ID, + 'log_per_date' => true, +]); +$_phpv = new CoreLibs\Check\PhpVersion(); +$phpv_class = 'CoreLibs\Check\PhpVersion'; + +$PAGE_NAME = 'TEST CLASS: PHP VERSION'; +print ""; +print "" . $PAGE_NAME . ""; +print ""; +print ''; +print '

' . $PAGE_NAME . '

'; + +// fputcsv +print "

\CoreLibs\DeprecatedHelper\Deprecated84::fputcsv()

"; +$test_csv = BASE . TMP . 'DeprecatedHelper.test.csv'; +print "File: $test_csv
"; + +$fp = fopen($test_csv, "w"); +if (!is_resource($fp)) { + die("Cannot open file: $test_csv"); +} +\CoreLibs\DeprecatedHelper\Deprecated84::fputcsv($fp, ["A", "B", "C"]); +fclose($fp); + +$fp = fopen($test_csv, "r"); +if (!is_resource($fp)) { + die("Cannot open file: $test_csv"); +} +while ($entry = \CoreLibs\DeprecatedHelper\Deprecated84::fgetcsv($fp)) { + print "fgetcsv:
" . print_r($entry, true) . "
"; +} +fclose($fp); + +$out = \CoreLibs\DeprecatedHelper\Deprecated84::str_getcsv("A,B,C"); +print "str_getcsv:
" . print_r($out, true) . "
"; + +/** + * temporary different CSV function, because fgetcsv seems to be broken on some systems + * (does not read out japanese text) + * + * @param string $string full line for csv split + * @param string $encoding optional, if given, converts string to the internal encoding + * before we do anything + * @param string $delimiter sepperate character, default ',' + * @param string $enclosure string line marker, default '"' + * @param string $flag INTERN | EXTERN. if INTERN uses the PHP function, else uses explode + * @return array array with split data from input line + */ +function mtParseCSV( + string $string, + string $encoding = '', + string $delimiter = ',', + string $enclosure = '"', + string $flag = 'INTERN' +): array { + $lines = []; + if ($encoding) { + $string = \CoreLibs\Convert\Encoding::convertEncoding( + $string, + 'UTF-8', + $encoding + ); + } + if ($flag == 'INTERN') { + // split with PHP function + $lines = str_getcsv($string, $delimiter, $enclosure); + } else { + // split up with delimiter + $lines = explode(',', $string) ?: []; + } + // strip " from beginning and end of line + for ($i = 0; $i < count($lines); $i++) { + // remove line breaks + $lines[$i] = preg_replace("/\r\n?/", '', (string)$lines[$i]) ?? ''; + // lingering " at the beginning and end of the line + $lines[$i] = preg_replace("/^\"/", '', (string)$lines[$i]) ?? ''; + $lines[$i] = preg_replace("/\"$/", '', (string)$lines[$i]) ?? ''; + } + return $lines; +} + +print ""; + +// __END__ diff --git a/www/admin/class_test.hash.php b/www/admin/class_test.hash.php index c269a5dc..bc4d7853 100644 --- a/www/admin/class_test.hash.php +++ b/www/admin/class_test.hash.php @@ -19,6 +19,7 @@ $LOG_FILE_ID = 'classTest-hash'; ob_end_flush(); use CoreLibs\Create\Hash; +use CoreLibs\Security\CreateKey; $log = new CoreLibs\Logging\Logging([ 'log_folder' => BASE . LOG, @@ -38,28 +39,66 @@ print '

' . $PAGE_NAME . '

'; $to_crc = 'Some text block'; // static -print "S::__CRC32B: $to_crc: " . $hash_class::__crc32b($to_crc) . "
"; -print "S::__SHA1SHORT(off): $to_crc: " . $hash_class::__sha1short($to_crc) . "
"; -print "S::__SHA1SHORT(on): $to_crc: " . $hash_class::__sha1short($to_crc, true) . "
"; -print "S::__hash(d): " . $to_crc . "/" - . Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "
"; -foreach (['adler32', 'fnv132', 'fnv1a32', 'joaat', 'sha512'] as $__hash_c) { - print "S::__hash($__hash_c): $to_crc: " . $hash_class::__hash($to_crc, $__hash_c) . "
"; +print "S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "
"; +// print "S::__SHA1SHORT(off): $to_crc: " . Hash::__sha1short($to_crc) . "
"; +print "S::hashShort(__sha1Short replace): $to_crc: " . Hash::hashShort($to_crc) . "
"; +// print "S::__SHA1SHORT(on): $to_crc: " . Hash::__sha1short($to_crc, true) . "
"; +print "S::sha1Short(__sha1Short replace): $to_crc: " . Hash::sha1Short($to_crc) . "
"; +// print "S::__hash(d): " . $to_crc . "/" +// . Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "
"; +$to_crc_list = [ + 'Some text block', + 'Some String Text', + 'any string', +]; +foreach ($to_crc_list as $__to_crc) { + foreach (['adler32', 'fnv132', 'fnv1a32', 'joaat', 'ripemd160', 'sha256', 'sha512'] as $__hash_c) { + print "Hash::hash($__hash_c): $__to_crc: " . Hash::hash($to_crc, $__hash_c) . "
"; + } } // static use print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "
"; echo "
"; $text = 'Some String Text'; +// $text = 'any string'; $type = 'crc32b'; print "Hash: " . $type . ": " . hash($type, $text) . "
"; -print "Class: " . $type . ": " . Hash::__hash($text, $type) . "
"; +// print "Class (old): " . $type . ": " . Hash::__hash($text, $type) . "
"; +print "Class (new): " . $type . ": " . Hash::hash($text, $type) . "
"; echo "
"; -print "
CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "
"; -print "
CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "
"; -print "HASH SHORT: " . $to_crc . ": " . Hash::__hash($to_crc) . "
"; -print "HASH LONG: " . $to_crc . ": " . Hash::__hashLong($to_crc) . "
"; +print "CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "
"; +print "CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "
"; +print "CURRENT STANDARD_HASH: " . Hash::STANDARD_HASH . "
"; +print "HASH SHORT: " . $to_crc . ": " . Hash::hashShort($to_crc) . "
"; +print "HASH LONG: " . $to_crc . ": " . Hash::hashLong($to_crc) . "
"; +print "HASH DEFAULT: " . $to_crc . ": " . Hash::hashStd($to_crc) . "
"; + +echo "
"; +$key = CreateKey::generateRandomKey(); +$key = "FIX KEY"; +print "Secret Key: " . $key . "
"; +print "HASHMAC DEFAULT (fix): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "
"; +$key = CreateKey::generateRandomKey(); +print "Secret Key: " . $key . "
"; +print "HASHMAC DEFAULT (random): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "
"; + +echo "
"; +$hash_types = ['crc32b', 'sha256', 'invalid']; +foreach ($hash_types as $hash_type) { + echo "Checking $hash_type:
"; + if (Hash::isValidHashType($hash_type)) { + echo "hash type: $hash_type is valid
"; + } else { + echo "hash type: $hash_type is INVALID
"; + } + if (Hash::isValidHashHmacType($hash_type)) { + echo "hash hmac type: $hash_type is valid
"; + } else { + echo "hash hmac type: $hash_type is INVALID
"; + } +} // print "UNIQU ID SHORT : " . Hash::__uniqId() . "
"; // print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "
"; diff --git a/www/admin/class_test.login.php b/www/admin/class_test.login.php index 2049635e..cba9927c 100644 --- a/www/admin/class_test.login.php +++ b/www/admin/class_test.login.php @@ -31,6 +31,7 @@ $log = new CoreLibs\Logging\Logging([ 'log_per_date' => true, ]); $db = new CoreLibs\DB\IO(DB_CONFIG, $log); +$log->setLogFileId('classTest-login-override'); $login = new CoreLibs\ACL\Login( $db, $log, @@ -45,6 +46,7 @@ $login = new CoreLibs\ACL\Login( 'locale_path' => BASE . INCLUDES . LOCALE, ] ); +$log->setLogFileId($LOG_FILE_ID); ob_end_flush(); $login->loginMainCall(); @@ -117,7 +119,7 @@ if (isset($login->loginGetAcl()['unit'])) { if ($login->loginCheckEditAccessCuid($edit_access_cuid)) { print "Set new:" . $edit_access_cuid . "
"; } else { - print "Load default unit id: " . $login->loginGetAcl()['unit_id'] . "
"; + print "Load default unit id: " . $login->loginGetAcl()['unit_cuid'] . "
"; } } else { print "Something went wrong with the login
"; @@ -127,6 +129,12 @@ if (isset($login->loginGetAcl()['unit'])) { // IP check: 'REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR', 'CLIENT_IP' in _SERVER // Agent check: 'HTTP_USER_AGENT' +print "
"; +print "PAGE lookup:
"; +$file_name = 'test_edit_base.php'; +print "Access to '$file_name': " . $log->prAr($login->loginPageAccessAllowed($file_name)) . "
"; +$file_name = 'i_do_not_exists.php'; +print "Access to '$file_name': " . $log->prAr($login->loginPageAccessAllowed($file_name)) . "
"; echo "
"; print "SESSION: " . Support::printAr($_SESSION) . "
"; @@ -140,4 +148,18 @@ $login->writeLog( write_type:'JSON' ); +echo "
"; +print "

Legacy Lookups

"; + +$edit_access_id = 1; +$edit_access_cuid = $login->loginGetEditAccessCuidFromId($edit_access_id); +$edit_access_id_rev = null; +if (is_string($edit_access_cuid)) { + $edit_access_id_rev = $login->loginGetEditAccessIdFromCuid($edit_access_cuid); +} +print "EA ID: " . $edit_access_id . "
"; +print "EA CUID: " . $log->prAr($edit_access_cuid) . "
"; +print "REV EA CUID: " . $log->prAr($edit_access_id_rev) . "
"; +$log->info('This is a test'); + print ""; diff --git a/www/admin/class_test.php b/www/admin/class_test.php index a54b2bce..0e2d6ad4 100644 --- a/www/admin/class_test.php +++ b/www/admin/class_test.php @@ -95,6 +95,7 @@ $test_files = [ 'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn', 'class_test.db.single.php' => 'Class Test: DB single query tests', 'class_test.db.convert-placeholder.php' => 'Class Test: DB convert placeholder', + 'class_test.db.encryption.php' => 'Class Test: DB pgcrypto', 'class_test.convert.colors.php' => 'Class Test: CONVERT COLORS', 'class_test.check.colors.php' => 'Class Test: CHECK COLORS', 'class_test.mime.php' => 'Class Test: MIME', @@ -141,6 +142,7 @@ $test_files = [ 'class_test.error_msg.php' => 'Class Test: ERROR MSG', 'class_test.url-requests.curl.php' => 'Class Test: URL REQUESTS: CURL', 'subfolder/class_test.config.direct.php' => 'Class Test: CONFIG DIRECT SUB', + 'class_test.deprecated.helper.php' => 'Class Test: DEPRECATED HELPERS', ]; asort($test_files); diff --git a/www/admin/class_test.phpv.php b/www/admin/class_test.phpv.php index 9e0d077d..648dca85 100644 --- a/www/admin/class_test.phpv.php +++ b/www/admin/class_test.phpv.php @@ -28,8 +28,6 @@ $log = new CoreLibs\Logging\Logging([ $_phpv = new CoreLibs\Check\PhpVersion(); $phpv_class = 'CoreLibs\Check\PhpVersion'; -// define a list of from to color sets for conversion test - $PAGE_NAME = 'TEST CLASS: PHP VERSION'; print ""; print "" . $PAGE_NAME . ""; diff --git a/www/admin/class_test.session.php b/www/admin/class_test.session.php index eb73256d..139e6a80 100644 --- a/www/admin/class_test.session.php +++ b/www/admin/class_test.session.php @@ -86,8 +86,10 @@ if (!isset($_SESSION['counter'])) { $_SESSION['counter']++; print "[READ] A " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "
"; $_SESSION[$var] = $value; +/** @phpstan-ignore-next-line nullCoalesce.offset */ print "[READ] B " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "
"; print "[READ] Confirm " . $var . " is " . $value . ": " +/** @phpstan-ignore-next-line equal.alwaysTrue, nullCoalesce.offset */ . (($_SESSION[$var] ?? '') == $value ? 'Matching' : 'Not matching') . "
"; // test set wrappers methods diff --git a/www/composer.lock b/www/composer.lock index 2d526e1b..ec0b5d56 100644 --- a/www/composer.lock +++ b/www/composer.lock @@ -12,14 +12,14 @@ "dist": { "type": "path", "url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All", - "reference": "a092217201ffac165dfcf72077c1fec14c759885" + "reference": "ec1fb72ba95699907605ac1507fe4c4dd7349896" }, "require": { "php": ">=8.2", "psr/log": "^3.0@dev" }, "require-dev": { - "egrajp/smarty-extended": "^4.3", + "egrajp/smarty-extended": "^5.4", "gullevek/dotenv": "dev-master", "phan/phan": "^5.4", "phpstan/phpdoc-parser": "^2.0", diff --git a/www/vendor/composer/installed.json b/www/vendor/composer/installed.json index 20aba712..ad51dcee 100644 --- a/www/vendor/composer/installed.json +++ b/www/vendor/composer/installed.json @@ -7,14 +7,14 @@ "dist": { "type": "path", "url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All", - "reference": "a092217201ffac165dfcf72077c1fec14c759885" + "reference": "ec1fb72ba95699907605ac1507fe4c4dd7349896" }, "require": { "php": ">=8.2", "psr/log": "^3.0@dev" }, "require-dev": { - "egrajp/smarty-extended": "^4.3", + "egrajp/smarty-extended": "^5.4", "gullevek/dotenv": "dev-master", "phan/phan": "^5.4", "phpstan/phpdoc-parser": "^2.0", diff --git a/www/vendor/composer/installed.php b/www/vendor/composer/installed.php index 044ff02f..53a77c90 100644 --- a/www/vendor/composer/installed.php +++ b/www/vendor/composer/installed.php @@ -13,7 +13,7 @@ 'egrajp/corelibs-composer-all' => array( 'pretty_version' => 'dev-development', 'version' => 'dev-development', - 'reference' => 'a092217201ffac165dfcf72077c1fec14c759885', + 'reference' => 'ec1fb72ba95699907605ac1507fe4c4dd7349896', 'type' => 'library', 'install_path' => __DIR__ . '/../egrajp/corelibs-composer-all', 'aliases' => array(), diff --git a/www/vendor/egrajp/corelibs-composer-all/composer.json b/www/vendor/egrajp/corelibs-composer-all/composer.json index 8d6fe360..1e9635d3 100644 --- a/www/vendor/egrajp/corelibs-composer-all/composer.json +++ b/www/vendor/egrajp/corelibs-composer-all/composer.json @@ -25,7 +25,7 @@ "phpstan/phpdoc-parser": "^2.0", "phpstan/phpstan-deprecation-rules": "^2.0", "phan/phan": "^5.4", - "egrajp/smarty-extended": "^4.3", + "egrajp/smarty-extended": "^5.4", "gullevek/dotenv": "dev-master", "phpunit/phpunit": "^9" }, diff --git a/www/vendor/egrajp/corelibs-composer-all/phpstan.neon b/www/vendor/egrajp/corelibs-composer-all/phpstan.neon index 20798b57..98b9e029 100644 --- a/www/vendor/egrajp/corelibs-composer-all/phpstan.neon +++ b/www/vendor/egrajp/corelibs-composer-all/phpstan.neon @@ -22,6 +22,9 @@ parameters: # - vendor # ignore errores with ignoreErrors: + - + message: '#Expression in empty\(\) is not falsy.#' + path: %currentWorkingDirectory%/src/Language/GetLocale.php #- # this error is ignore because of the PHP 8.0 to 8.1 change for pg_*, only for 8.0 or lower # message: "#^Parameter \\#1 \\$(result|connection) of function pg_\\w+ expects resource(\\|null)?, object\\|resource(\\|bool)? given\\.$#" # path: %currentWorkingDirectory%/www/lib/CoreLibs/DB/SQL/PgSQL.php diff --git a/www/vendor/egrajp/corelibs-composer-all/publish/last.published b/www/vendor/egrajp/corelibs-composer-all/publish/last.published index 2c53cf23..d95eff75 100644 --- a/www/vendor/egrajp/corelibs-composer-all/publish/last.published +++ b/www/vendor/egrajp/corelibs-composer-all/publish/last.published @@ -1 +1 @@ -9.25.3 +9.33.0 diff --git a/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php b/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php index 0b6c55ad..e9d3dc97 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php @@ -423,14 +423,9 @@ class Login // LOGOUT TARGET if (!isset($options['logout_target'])) { - if (defined('LOGOUT_TARGET')) { - trigger_error( - 'loginMainCall: LOGOUT_TARGET should not be used', - E_USER_DEPRECATED - ); - $options['logout_target'] = LOGOUT_TARGET; - $this->logout_target = $options['logout_target']; - } + // defaults to '' + $options['logout_target'] = ''; + $this->logout_target = $options['logout_target']; } // *** PASSWORD SETTINGS @@ -929,7 +924,9 @@ class Login $mandatory_session_vars = [ 'LOGIN_USER_NAME', 'LOGIN_GROUP_NAME', 'LOGIN_EUCUID', 'LOGIN_EUCUUID', 'LOGIN_USER_ADDITIONAL_ACL', 'LOGIN_GROUP_ADDITIONAL_ACL', - 'LOGIN_ADMIN', 'LOGIN_GROUP_ACL_LEVEL', 'LOGIN_PAGES_ACL_LEVEL', 'LOGIN_USER_ACL_LEVEL', + 'LOGIN_ADMIN', 'LOGIN_GROUP_ACL_LEVEL', + 'LOGIN_PAGES', 'LOGIN_PAGES_LOOKUP', 'LOGIN_PAGES_ACL_LEVEL', + 'LOGIN_USER_ACL_LEVEL', 'LOGIN_UNIT', 'LOGIN_UNIT_DEFAULT_EACUID' ]; $force_reauth = false; @@ -1157,7 +1154,7 @@ class Login $q ); // reset any query data that might exist - $this->db->dbCacheReset($q, $params); + $this->db->dbCacheReset($q, $params, show_warning:false); // never cache return data $res = $this->db->dbReturnParams($q, $params, $this->db::NO_CACHE); // query was not run successful @@ -1269,6 +1266,7 @@ class Login } $edit_page_ids = []; $pages = []; + $pages_lookup = []; $pages_acl = []; // set pages access $q = << [], 'visible' => [] ]; + $pages_lookup[$res['filename']] = $res['cuid']; // make reference filename -> level $pages_acl[$res['filename']] = $res['level']; } // for each page @@ -1372,6 +1371,7 @@ class Login // write back the pages data to the output array $this->session->setMany([ 'LOGIN_PAGES' => $pages, + 'LOGIN_PAGES_LOOKUP' => $pages_lookup, 'LOGIN_PAGES_ACL_LEVEL' => $pages_acl, ]); // load the edit_access user rights @@ -1418,6 +1418,7 @@ class Login 'additional_acl' => Json::jsonConvertToArray($res['additional_acl']), 'data' => $ea_data ]; + // LEGACY LOOKUP $unit_access_eaid[$res['edit_access_id']] = [ 'cuid' => $res['cuid'], ]; @@ -1477,6 +1478,8 @@ class Login // username (login), group name $this->acl['user_name'] = $_SESSION['LOGIN_USER_NAME']; $this->acl['group_name'] = $_SESSION['LOGIN_GROUP_NAME']; + // DEPRECATED + $this->acl['euid'] = $_SESSION['LOGIN_EUID']; // edit user cuid $this->acl['eucuid'] = $_SESSION['LOGIN_EUCUID']; $this->acl['eucuuid'] = $_SESSION['LOGIN_EUCUUID']; @@ -1528,8 +1531,10 @@ class Login ) { $this->acl['page'] = $_SESSION['LOGIN_PAGES_ACL_LEVEL'][$this->page_name]; } + $this->acl['pages_detail'] = $_SESSION['LOGIN_PAGES']; + $this->acl['pages_lookup_cuid'] = $_SESSION['LOGIN_PAGES_LOOKUP']; - $this->acl['unit_id'] = null; + $this->acl['unit_cuid'] = null; $this->acl['unit_name'] = null; $this->acl['unit_uid'] = null; $this->acl['unit'] = []; @@ -1552,9 +1557,12 @@ class Login $this->acl['unit_legacy'][$unit['id']] = $this->acl['unit'][$ea_cuid]; // detail name/level set $this->acl['unit_detail'][$ea_cuid] = [ + 'id' => $unit['id'], 'name' => $unit['name'], 'uid' => $unit['uid'], + 'cuuid' => $unit['cuuid'], 'level' => $this->default_acl_list[$this->acl['unit'][$ea_cuid]]['name'] ?? -1, + 'level_number' => $this->acl['unit'][$ea_cuid], 'default' => $unit['default'], 'data' => $unit['data'], 'additional_acl' => $unit['additional_acl'] @@ -2533,7 +2541,7 @@ HTML; $this->login_user_id, -1, $login_user_id_changed - ); + ) ?? ''; // flag unclean input data if ($login_user_id_changed > 0) { $this->login_user_id_unclear = true; @@ -2727,6 +2735,31 @@ HTML; return $this->session->get('LOGIN_PAGES'); } + /** + * Return the current loaded list of pages the user can access + * + * @return array + */ + public function loginGetPageLookupList(): array + { + return $this->session->get('LOGIN_PAGES_LOOKUP'); + } + + /** + * Check access to a file in the pages list + * + * @param string $filename File name to check + * @return bool True if page in list and anything other than None access, False if failed + */ + public function loginPageAccessAllowed(string $filename): bool + { + return ( + $this->session->get('LOGIN_PAGES')[ + $this->session->get('LOGIN_PAGES_LOOKUP')[$filename] ?? '' + ] ?? 0 + ) != 0 ? true : false; + } + // MARK: logged in uid(pk)/eucuid/eucuuid /** @@ -3212,7 +3245,7 @@ HTML; * @return int|null same edit access id if ok * or the default edit access id * if given one is not valid - * @deprecated Please switch to using edit access cuid check with ->loginCheckEditAccessValidCuid() + * @#deprecated Please switch to using edit access cuid check with ->loginCheckEditAccessValidCuid() */ public function loginCheckEditAccessId(?int $edit_access_id): ?int { @@ -3277,6 +3310,34 @@ HTML; return (int)$_SESSION['LOGIN_UNIT_CUID'][$uid]; } + /** + * Legacy lookup for edit access id to cuid + * + * @param int $id edit access id PK + * @return string|false edit access cuid or false if not found + */ + public function loginGetEditAccessCuidFromId(int $id): string|false + { + if (!isset($_SESSION['LOGIN_UNIT_LEGACY'][$id])) { + return false; + } + return (string)$_SESSION['LOGIN_UNIT_LEGACY'][$id]['cuid']; + } + + /** + * This is a Legacy lookup from the edit access id to cuid for further lookups in the normal list + * + * @param string $cuid edit access cuid + * @return int|false false on not found or edit access id PK + */ + public function loginGetEditAccessIdFromCuid(string $cuid): int|false + { + if (!isset($_SESSION['LOGIN_UNIT'][$cuid])) { + return false; + } + return $_SESSION['LOGIN_UNIT'][$cuid]['id']; + } + /** * Check if admin flag is set * diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Admin/Backend.php b/www/vendor/egrajp/corelibs-composer-all/src/Admin/Backend.php index 04e084ff..cd64e2e1 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Admin/Backend.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Admin/Backend.php @@ -289,7 +289,7 @@ class Backend * JSON, STRING/SERIEAL, BINARY/BZIP or ZLIB * @param string|null $db_schema [default=null] override target schema * @return void - * @deprecated Use $login->writeLog() and set action_set from ->adbGetActionSet() + * @deprecated Use $login->writeLog($event, $data, action_set:$cms->adbGetActionSet(), write_type:$write_type) */ public function adbEditLog( string $event = '', diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Admin/EditBase.php b/www/vendor/egrajp/corelibs-composer-all/src/Admin/EditBase.php index 20312b52..754c33b5 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Admin/EditBase.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Admin/EditBase.php @@ -76,7 +76,7 @@ class EditBase ); if ($this->form->mobile_phone) { echo "I am sorry, but this page cannot be viewed by a mobile phone"; - exit; + exit(1); } // $this->log->debug('POST', $this->log->prAr($_POST)); } diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Basic.php b/www/vendor/egrajp/corelibs-composer-all/src/Basic.php index db57672a..1eb3410f 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Basic.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Basic.php @@ -103,11 +103,7 @@ class Basic 'VIDEOS', 'DOCUMENTS', 'PDFS', 'BINARIES', 'ICONS', 'UPLOADS', 'CSV', 'JS', 'CSS', 'TABLE_ARRAYS', 'SMARTY', 'LANG', 'CACHE', 'TMP', 'LOG', 'TEMPLATES', 'TEMPLATES_C', 'DEFAULT_LANG', 'DEFAULT_ENCODING', 'DEFAULT_HASH', - 'DEFAULT_ACL_LEVEL', 'LOGOUT_TARGET', 'PASSWORD_CHANGE', 'AJAX_REQUEST_TYPE', - 'USE_PROTOTYPE', 'USE_SCRIPTACULOUS', 'USE_JQUERY', 'PAGE_WIDTH', - 'MASTER_TEMPLATE_NAME', 'PUBLIC_SCHEMA', 'TEST_SCHEMA', 'DEV_SCHEMA', - 'LIVE_SCHEMA', 'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET', 'DEBUG', - 'SHOW_ALL_ERRORS' + 'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET' ] as $constant ) { if (!defined($constant)) { @@ -1028,8 +1024,12 @@ class Basic */ public function __sha1Short(string $string, bool $use_sha = false): string { - trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::__sha1Short()', E_USER_DEPRECATED); - return \CoreLibs\Create\Hash::__sha1Short($string, $use_sha); + trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::sha1Short() or ::__crc32b()', E_USER_DEPRECATED); + if ($use_sha) { + return \CoreLibs\Create\Hash::sha1Short($string); + } else { + return \CoreLibs\Create\Hash::__crc32b($string); + } } /** @@ -1044,8 +1044,8 @@ class Basic */ public function __hash(string $string, string $hash_type = 'adler32'): string { - trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::__hash()', E_USER_DEPRECATED); - return \CoreLibs\Create\Hash::__hash($string, $hash_type); + trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::hash()', E_USER_DEPRECATED); + return \CoreLibs\Create\Hash::hash($string, $hash_type); } // *** HASH FUNCTIONS END diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Combined/ArrayHandler.php b/www/vendor/egrajp/corelibs-composer-all/src/Combined/ArrayHandler.php index bd9a3b58..dae3e1e9 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Combined/ArrayHandler.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Combined/ArrayHandler.php @@ -551,6 +551,36 @@ class ArrayHandler ARRAY_FILTER_USE_KEY ); } + + /** + * 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 $in_array + * @param string $key_mod_prefix [default=''] key prefix string + * @param string $key_mod_suffix [default=''] key suffix string + * @return array + */ + public static function arrayModifyKey( + array $in_array, + string $key_mod_prefix = '', + string $key_mod_suffix = '' + ): array { + // skip if array is empty or neither prefix or suffix are set + if ( + $in_array == [] || + ($key_mod_prefix == '' && $key_mod_suffix == '') + ) { + return $in_array; + } + return array_combine( + array_map( + fn($key) => $key_mod_prefix . $key . $key_mod_suffix, + array_keys($in_array) + ), + array_values($in_array) + ); + } } // __END__ diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Combined/DateTime.php b/www/vendor/egrajp/corelibs-composer-all/src/Combined/DateTime.php index d46619c5..b86bdee2 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Combined/DateTime.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Combined/DateTime.php @@ -639,16 +639,26 @@ class DateTime * * @param string $start_date valid start date (y/m/d) * @param string $end_date valid end date (y/m/d) - * @param bool $return_named return array type, false (default), true for named - * @return array 0/overall, 1/weekday, 2/weekend + * @param bool $return_named [default=false] return array type, false (default), true for named + * @param bool $include_end_date [default=true] include end date in calc + * @param bool $exclude_start_date [default=false] include end date in calc + * @return array{0:int,1:int,2:int,3:bool}|array{overall:int,weekday:int,weekend:int,reverse:bool} + * 0/overall, 1/weekday, 2/weekend, 3/reverse */ public static function calcDaysInterval( string $start_date, string $end_date, - bool $return_named = false + bool $return_named = false, + bool $include_end_date = true, + bool $exclude_start_date = false ): array { // pos 0 all, pos 1 weekday, pos 2 weekend - $days = []; + $days = [ + 0 => 0, + 1 => 0, + 2 => 0, + 3 => false, + ]; // if anything invalid, return 0,0,0 try { $start = new \DateTime($start_date); @@ -659,19 +669,30 @@ class DateTime 'overall' => 0, 'weekday' => 0, 'weekend' => 0, + 'reverse' => false ]; } else { - return [0, 0, 0]; + return $days; } } // 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; + // if start is before end, switch dates and flag + $days[3] = false; + if ($start > $end) { + $new_start = $end; + $end = $start; + $start = $new_start; + $days[3] = true; + } // get period for weekends/weekdays - $period = new \DatePeriod($start, new \DateInterval('P1D'), $end); + $options = 0; + if ($include_end_date) { + $options |= \DatePeriod::INCLUDE_END_DATE; + } + if ($exclude_start_date) { + $options |= \DatePeriod::EXCLUDE_START_DATE; + } + $period = new \DatePeriod($start, new \DateInterval('P1D'), $end, $options); foreach ($period as $dt) { $curr = $dt->format('D'); if ($curr == 'Sat' || $curr == 'Sun') { @@ -679,18 +700,80 @@ class DateTime } else { $days[1]++; } + $days[0]++; } if ($return_named === true) { return [ 'overall' => $days[0], 'weekday' => $days[1], 'weekend' => $days[2], + 'reverse' => $days[3], ]; } else { return $days; } } + /** + * wrapper for calcDaysInterval with numeric return only + * + * @param string $start_date valid start date (y/m/d) + * @param string $end_date valid end date (y/m/d) + * @param bool $include_end_date [default=true] include end date in calc + * @param bool $exclude_start_date [default=false] include end date in calc + * @return array{0:int,1:int,2:int,3:bool} + */ + public static function calcDaysIntervalNumIndex( + string $start_date, + string $end_date, + bool $include_end_date = true, + bool $exclude_start_date = false + ): array { + $values = self::calcDaysInterval( + $start_date, + $end_date, + false, + $include_end_date, + $exclude_start_date + ); + return [ + $values[0] ?? 0, + $values[1] ?? 0, + $values[2] ?? 0, + $values[3] ?? false, + ]; + } + + /** + * wrapper for calcDaysInterval with named return only + * + * @param string $start_date valid start date (y/m/d) + * @param string $end_date valid end date (y/m/d) + * @param bool $include_end_date [default=true] include end date in calc + * @param bool $exclude_start_date [default=false] include end date in calc + * @return array{overall:int,weekday:int,weekend:int,reverse:bool} + */ + public static function calcDaysIntervalNamedIndex( + string $start_date, + string $end_date, + bool $include_end_date = true, + bool $exclude_start_date = false + ): array { + $values = self::calcDaysInterval( + $start_date, + $end_date, + true, + $include_end_date, + $exclude_start_date + ); + return [ + 'overall' => $values['overall'] ?? 0, + 'weekday' => $values['weekday'] ?? 0, + 'weekend' => $values['weekend'] ?? 0, + 'reverse' => $values['reverse'] ?? false, + ]; + } + /** * check if a weekend day (sat/sun) is in the given date range * Can have time too, but is not needed @@ -705,6 +788,13 @@ class DateTime ): bool { $dd_start = new \DateTime($start_date); $dd_end = new \DateTime($end_date); + // flip if start is after end + if ($dd_start > $dd_end) { + $new_start = $dd_end; + $dd_end = $dd_start; + $dd_start = $new_start; + } + // if start > end, flip if ( // starts with a weekend $dd_start->format('N') >= 6 || diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Convert/Html.php b/www/vendor/egrajp/corelibs-composer-all/src/Convert/Html.php index 2094dc55..ae057662 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Convert/Html.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Convert/Html.php @@ -10,9 +10,16 @@ namespace CoreLibs\Convert; class Html { + /** @var int */ public const SELECTED = 0; + /** @var int */ public const CHECKED = 1; + // TODO: check for not valid htmlentites encoding + // as of PHP 8.4: https://www.php.net/manual/en/function.htmlentities.php + /** @#var array */ + // public const VALID_HTMLENT_ENCODINGS = []; + /** * full wrapper for html entities * @@ -22,14 +29,19 @@ class Html * encodes in UTF-8 * does not double encode * - * @param mixed $string string to html encode - * @param int $flags [default: ENT_QUOTES | ENT_HTML5] + * @param mixed $string string to html encode + * @param int $flags [default=ENT_QUOTES | ENT_HTML5] + * @param string $encoding [default=UTF-8] * @return mixed if string, encoded, else as is (eg null) */ - public static function htmlent(mixed $string, int $flags = ENT_QUOTES | ENT_HTML5): mixed - { + public static function htmlent( + mixed $string, + int $flags = ENT_QUOTES | ENT_HTML5, + string $encoding = 'UTF-8' + ): mixed { if (is_string($string)) { - return htmlentities($string, $flags, 'UTF-8', false); + // if not a valid encoding this will throw a warning and use UTF-8 + return htmlentities($string, $flags, $encoding, false); } return $string; } @@ -37,7 +49,7 @@ class Html /** * strips out all line breaks or replaced with given string * @param string $string string - * @param string $replace replace character, default ' ' + * @param string $replace [default=' '] replace character * @return string cleaned string without any line breaks */ public static function removeLB(string $string, string $replace = ' '): string diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Create/Hash.php b/www/vendor/egrajp/corelibs-composer-all/src/Create/Hash.php index bf83afeb..9ed734db 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Create/Hash.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Create/Hash.php @@ -10,9 +10,14 @@ namespace CoreLibs\Create; class Hash { + /** @var string default short hash -> deprecated use STANDARD_HASH_SHORT */ public const DEFAULT_HASH = 'adler32'; + /** @var string default long hash (40 chars) */ public const STANDARD_HASH_LONG = 'ripemd160'; + /** @var string default short hash (8 chars) */ public const STANDARD_HASH_SHORT = 'adler32'; + /** @var string this is the standard hash to use hashStd and hash (64 chars) */ + public const STANDARD_HASH = 'sha256'; /** * checks php version and if >=5.2.7 it will flip the string @@ -20,6 +25,7 @@ class Hash * hash returns false * preg_replace fails for older php version * Use __hash with crc32b or hash('crc32b', ...) for correct output + * For future short hashes use hashShort() instead * * @param string $string string to crc * @return string crc32b hash (old type) @@ -43,19 +49,31 @@ class Hash * replacement for __crc32b call * * @param string $string string to hash - * @param bool $use_sha use sha instead of crc32b (default false) + * @param bool $use_sha [default=false] use sha1 instead of crc32b * @return string hash of the string + * @deprecated use __crc32b() for drop in replacement with default, or sha1Short() for use sha true */ public static function __sha1Short(string $string, bool $use_sha = false): string { if ($use_sha) { - // return only the first 9 characters - return substr(hash('sha1', $string), 0, 9); + return self::sha1Short($string); } else { return self::__crc32b($string); } } + /** + * returns a short sha1 + * + * @param string $string string to hash + * @return string hash of the string + */ + public static function sha1Short(string $string): string + { + // return only the first 9 characters + return substr(hash('sha1', $string), 0, 9); + } + /** * replacemend for __crc32b call (alternate) * defaults to adler 32 @@ -63,34 +81,135 @@ class Hash * all that create 8 char long hashes * * @param string $string string to hash - * @param string $hash_type hash type (default adler32) + * @param string $hash_type [default=STANDARD_HASH_SHORT] hash type (default adler32) * @return string hash of the string + * @deprecated use hashShort() of short hashes with adler 32 or hash() for other hash types */ public static function __hash( string $string, - string $hash_type = self::DEFAULT_HASH + string $hash_type = self::STANDARD_HASH_SHORT + ): string { + return self::hash($string, $hash_type); + } + + /** + * check if hash type is valid, returns false if not + * + * @param string $hash_type + * @return bool + */ + public static function isValidHashType(string $hash_type): bool + { + if (!in_array($hash_type, hash_algos())) { + return false; + } + return true; + } + + /** + * check if hash hmac type is valid, returns false if not + * + * @param string $hash_hmac_type + * @return bool + */ + public static function isValidHashHmacType(string $hash_hmac_type): bool + { + if (!in_array($hash_hmac_type, hash_hmac_algos())) { + return false; + } + return true; + } + + /** + * creates a hash over string if any valid hash given. + * if no hash type set use sha256 + * + * @param string $string string to hash + * @param string $hash_type [default=STANDARD_HASH] hash type (default sha256) + * @return string hash of the string + */ + public static function hash( + string $string, + string $hash_type = self::STANDARD_HASH ): string { - // if not empty, check if in valid list if ( empty($hash_type) || !in_array($hash_type, hash_algos()) ) { - // fallback to default hash type if none set or invalid - $hash_type = self::DEFAULT_HASH; + // fallback to default hash type if empty or invalid + $hash_type = self::STANDARD_HASH; } return hash($hash_type, $string); } /** - * Wrapper function for standard long hashd + * creates a hash mac key + * + * @param string $string string to hash mac + * @param string $key key to use + * @param string $hash_type [default=STANDARD_HASH] + * @return string hash mac string + */ + public static function hashHmac( + string $string, + #[\SensitiveParameter] + string $key, + string $hash_type = self::STANDARD_HASH + ): string { + if ( + empty($hash_type) || + !in_array($hash_type, hash_hmac_algos()) + ) { + // fallback to default hash type if e or invalid + $hash_type = self::STANDARD_HASH; + } + return hash_hmac($hash_type, $string, $key); + } + + /** + * short hash with max length of 8, uses adler32 + * + * @param string $string string to hash + * @return string hash of the string + */ + public static function hashShort(string $string): string + { + return hash(self::STANDARD_HASH_SHORT, $string); + } + + /** + * Wrapper function for standard long hash + * + * @param string $string String to be hashed + * @return string Hashed string + * @deprecated use hashLong() + */ + public static function __hashLong(string $string): string + { + return self::hashLong($string); + } + + /** + * Wrapper function for standard long hash, uses ripmd160 * * @param string $string String to be hashed * @return string Hashed string */ - public static function __hashLong(string $string): string + public static function hashLong(string $string): string { return hash(self::STANDARD_HASH_LONG, $string); } + + /** + * create standard hash basd on STANDAR_HASH, currently sha256 + * + * @param string $string string in + * @return string hash of the string + */ + public static function hashStd(string $string): string + { + return self::hash($string, self::STANDARD_HASH); + } } // __END__ diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/Extended/ArrayIO.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/Extended/ArrayIO.php index ac98091c..50256c6a 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/DB/Extended/ArrayIO.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/Extended/ArrayIO.php @@ -39,9 +39,9 @@ class ArrayIO extends \CoreLibs\DB\IO { // main calss variables /** @var array */ - private array $table_array; // the array from the table to work on + private array $table_array = []; // the array from the table to work on /** @var string */ - private string $table_name; // the table_name + private string $table_name = ''; // the table_name /** @var string */ private string $pk_name = ''; // the primary key from this table /** @var int|string|null */ @@ -127,9 +127,9 @@ class ArrayIO extends \CoreLibs\DB\IO public function getTableArray(bool $reset = false): array { if (!$reset) { - return $this->table_array ?? []; + return $this->table_array; } - $table_array = $this->table_array ?? []; + $table_array = $this->table_array; reset($table_array); return $table_array; } @@ -194,7 +194,7 @@ class ArrayIO extends \CoreLibs\DB\IO */ public function getTableName(): string { - return $this->table_name ?? ''; + return $this->table_name; } /** diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/IO.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/IO.php index 4daad5b8..732d7a27 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/DB/IO.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/IO.php @@ -303,6 +303,8 @@ class IO private string $query = ''; /** @var array current params for query */ private array $params = []; + /** @var string current hash build from query and params */ + private string $query_hash = ''; // if we do have a convert call, store the convert data in here, else it will be empty /** @var array{}|array{original:array{query:string,params:array},type:''|'named'|'numbered'|'question_mark',found:int,matches:array,params_lookup:array,query:string,params:array} */ private array $placeholder_converted = []; @@ -500,7 +502,7 @@ class IO die(''); } // write to internal one, once OK - $this->db_functions = $db_functions; + $this->db_functions = $db_functions; /** @phan-suppress-current-line PhanPossiblyNullTypeMismatchProperty */ // connect to DB if (!$this->__connectToDB()) { @@ -1319,7 +1321,7 @@ class IO */ private function __dbCountQueryParams(string $query): int { - return $this->db_functions->__dbCountQueryParams($query); + return count($this->db_functions->__dbGetQueryParams($query)); } /** @@ -1382,6 +1384,8 @@ class IO $this->query = $query; // current params $this->params = $params; + // empty on new + $this->query_hash = ''; // no query set if (empty($this->query)) { $this->__dbError(11); @@ -1413,10 +1417,7 @@ class IO $this->pk_name_table[$table] ? $this->pk_name_table[$table] : 'NULL'; } - if ( - !preg_match(self::REGEX_RETURNING, $this->query) && - $this->pk_name && $this->pk_name != 'NULL' - ) { + if (!preg_match(self::REGEX_RETURNING, $this->query) && $this->pk_name != 'NULL') { // check if this query has a ; at the end and remove it $__query = preg_replace("/(;\s*)$/", '', $this->query); // must be query, if preg replace failed, use query as before @@ -1426,7 +1427,7 @@ class IO } elseif ( preg_match(self::REGEX_RETURNING, $this->query, $matches) ) { - if ($this->pk_name && $this->pk_name != 'NULL') { + if ($this->pk_name != 'NULL') { // add the primary key if it is not in the returning set if (!preg_match("/$this->pk_name/", $matches[1])) { $this->query .= " , " . $this->pk_name; @@ -1444,7 +1445,7 @@ class IO $this->returning_id = true; } // import protection, hash needed - $query_hash = $this->dbGetQueryHash($this->query, $this->params); + $query_hash = $this->dbBuildQueryHash($this->query, $this->params); // QUERY PARAMS: run query params check and rewrite if ($this->dbGetConvertPlaceholder() === true) { try { @@ -1478,7 +1479,8 @@ class IO return false; } } - + // set query hash + $this->query_hash = $query_hash; // $this->debug('DB IO', 'Q: ' . $this->query . ', RETURN: ' . $this->returning_id); // for DEBUG, only on first time ;) $this->__dbDebug( @@ -1962,7 +1964,7 @@ class IO { // set start array if ($query) { - $array = $this->cursor_ext[$this->dbGetQueryHash($query)] ?? []; + $array = $this->cursor_ext[$this->dbBuildQueryHash($query)] ?? []; } else { $array = $this->cursor_ext; } @@ -2364,7 +2366,7 @@ class IO return false; } // create hash from query ... - $query_hash = $this->dbGetQueryHash($query, $params); + $query_hash = $this->dbBuildQueryHash($query, $params); // pre declare array if (!isset($this->cursor_ext[$query_hash])) { $this->cursor_ext[$query_hash] = [ @@ -2542,7 +2544,10 @@ class IO } // only go if NO cursor exists // if cursor exists ... - if ($this->cursor_ext[$query_hash]['cursor']) { + if ( + $this->cursor_ext[$query_hash]['cursor'] instanceof \PgSql\Result || + $this->cursor_ext[$query_hash]['cursor'] == 1 + ) { if ($first_call === true) { $this->cursor_ext[$query_hash]['log'][] = 'First call'; // count the rows returned (if select) @@ -2940,13 +2945,15 @@ class IO * data to create a unique call one, optional * @return bool False if query not found, true if success */ - public function dbCacheReset(string $query, array $params = []): bool + public function dbCacheReset(string $query, array $params = [], bool $show_warning = true): bool { - $this->__dbErrorReset(); - $query_hash = $this->dbGetQueryHash($query, $params); + $query_hash = $this->dbBuildQueryHash($query, $params); // clears cache for this query - if (empty($this->cursor_ext[$query_hash]['query'])) { - $this->__dbError(18, context: [ + if ( + $show_warning && + empty($this->cursor_ext[$query_hash]['query']) + ) { + $this->__dbWarning(18, context: [ 'query' => $query, 'params' => $params, 'hash' => $query_hash, @@ -2985,7 +2992,7 @@ class IO if ($query === null) { return $this->cursor_ext; } - $query_hash = $this->dbGetQueryHash($query, $params); + $query_hash = $this->dbBuildQueryHash($query, $params); if ( !empty($this->cursor_ext) && isset($this->cursor_ext[$query_hash]) @@ -3015,7 +3022,7 @@ class IO $this->__dbError(11); return false; } - $query_hash = $this->dbGetQueryHash($query, $params); + $query_hash = $this->dbBuildQueryHash($query, $params); if ( !empty($this->cursor_ext) && isset($this->cursor_ext[$query_hash]) @@ -3041,7 +3048,7 @@ class IO $this->__dbError(11); return false; } - $query_hash = $this->dbGetQueryHash($query, $params); + $query_hash = $this->dbBuildQueryHash($query, $params); if ( !empty($this->cursor_ext) && isset($this->cursor_ext[$query_hash]) @@ -3067,7 +3074,7 @@ class IO */ public function dbResetQueryCalled(string $query, array $params = []): void { - $this->query_called[$this->dbGetQueryHash($query, $params)] = 0; + $this->query_called[$this->dbBuildQueryHash($query, $params)] = 0; } /** @@ -3080,7 +3087,7 @@ class IO */ public function dbGetQueryCalled(string $query, array $params = []): int { - $query_hash = $this->dbGetQueryHash($query, $params); + $query_hash = $this->dbBuildQueryHash($query, $params); if (!empty($this->query_called[$query_hash])) { return $this->query_called[$query_hash]; } else { @@ -3141,6 +3148,7 @@ class IO 'pk_name' => '', 'count' => 0, 'query' => '', + 'query_raw' => $query, 'result' => null, 'returning_id' => false, 'placeholder_converted' => [], @@ -3237,11 +3245,12 @@ class IO } } else { // if we try to use the same statement name for a differnt query, error abort - if ($this->prepare_cursor[$stm_name]['query'] != $query) { + if ($this->prepare_cursor[$stm_name]['query_raw'] != $query) { // thrown error $this->__dbError(26, false, context: [ 'statement_name' => $stm_name, 'prepared_query' => $this->prepare_cursor[$stm_name]['query'], + 'prepared_query_raw' => $this->prepare_cursor[$stm_name]['query_raw'], 'query' => $query, 'pk_name' => $pk_name, ]); @@ -4047,7 +4056,7 @@ class IO } /** - * Returns hash for query + * Creates hash for query and parameters * Hash is used in all internal storage systems for return data * * @param string $query The query to create the hash from @@ -4055,9 +4064,9 @@ class IO * data to create a unique call one, optional * @return string Hash, as set by hash long */ - public function dbGetQueryHash(string $query, array $params = []): string + public function dbBuildQueryHash(string $query, array $params = []): string { - return Hash::__hashLong( + return Hash::hashLong( $query . ( $params !== [] ? '#' . json_encode($params) : '' @@ -4105,6 +4114,26 @@ class IO $this->params = []; } + /** + * get the current set query hash + * + * @return string Current Query hash + */ + public function dbGetQueryHash(): string + { + return $this->query_hash; + } + + /** + * reset query hash + * + * @return void + */ + public function dbResetQueryHash(): void + { + $this->query_hash = ''; + } + /** * Returns the placeholder convert set or empty * @@ -4284,6 +4313,17 @@ class IO return $this->field_names[$pos] ?? false; } + /** + * get all the $ placeholders + * + * @param string $query + * @return array + */ + public function dbGetQueryParamPlaceholders(string $query): array + { + return $this->db_functions->__dbGetQueryParams($query); + } + /** * Return a field type for a field name or pos, * will return false if field is not found in list @@ -4364,6 +4404,37 @@ class IO return $this->prepare_cursor[$stm_name][$key]; } + /** + * Checks if a prepared query eixsts + * + * @param string $stm_name Statement to check + * @param string $query [default=''] If set then query must also match + * @return false|int<0,2> False on missing stm_name + * 0: ok, 1: stm_name matchin, 2: stm_name and query matching + */ + public function dbPreparedCursorStatus(string $stm_name, string $query = ''): false|int + { + if (empty($stm_name)) { + $this->__dbError( + 101, + false, + 'No statement name given' + ); + return false; + } + // does not exist + $return_value = 0; + if (!empty($this->prepare_cursor[$stm_name]['query_raw'])) { + // statement name eixts + $return_value = 1; + if ($this->prepare_cursor[$stm_name]['query_raw'] == $query) { + // query also matches + $return_value = 2; + } + } + return $return_value; + } + // *************************** // ERROR AND WARNING DATA // *************************** diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php index 8ccfa9a6..5dda8fa9 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php @@ -379,9 +379,9 @@ interface SqlFunctions * Undocumented function * * @param string $query - * @return int + * @return array */ - public function __dbCountQueryParams(string $query): int; + public function __dbGetQueryParams(string $query): array; } // __END__ diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php index a343c8bc..c05195c2 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php @@ -978,12 +978,12 @@ class PgSQL implements Interface\SqlFunctions } /** - * Count placeholder queries. $ only + * Get the all the $ params, as a unique list * * @param string $query - * @return int + * @return array */ - public function __dbCountQueryParams(string $query): int + public function __dbGetQueryParams(string $query): array { $matches = []; // regex for params: only stand alone $number allowed @@ -998,11 +998,11 @@ class PgSQL implements Interface\SqlFunctions // Matches in 1:, must be array_filtered to remove empty, count with array_unique // Regex located in the ConvertPlaceholder class preg_match_all( - ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS, + ConvertPlaceholder::REGEX_LOOKUP_NUMBERED, $query, $matches ); - return count(array_unique(array_filter($matches[3]))); + return array_unique(array_filter($matches[ConvertPlaceholder::MATCHING_POS])); } } diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/Support/ConvertPlaceholder.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/Support/ConvertPlaceholder.php index 484b7828..9fbbf876 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/DB/Support/ConvertPlaceholder.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/Support/ConvertPlaceholder.php @@ -14,76 +14,57 @@ namespace CoreLibs\DB\Support; class ConvertPlaceholder { - // NOTE for missing: range */+ are not iplemented in the regex below, but - is for now - // NOTE some combinations are allowed, but the query will fail before this - /** @var string split regex, entries before $ group */ - private const PATTERN_QUERY_SPLIT = - '\?\?|' // UNKNOWN: double ??, is this to avoid something? - . '[\(,]|' // for ',' and '(' mostly in INSERT or ANY() - . '[<>=]|' // general set for <, >, = in any query with any combination - . '\^@|' // text search for start from text with ^@ - . '\|\||' // concats two elements - . '&&|' // array overlap - . '\-\|\-|' // range overlap for array - . '[^-]-{1}|' // single -, used in JSON too - . '->|->>|#>|#>>|@>|<@|@@|@\?|\?{1}|\?\||\?&|#-|' // JSON searches, Array searchs, etc - . 'THEN|ELSE' // command parts (CASE) - ; - /** @var string the main regex including the pattern query split */ - private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:' . self::PATTERN_QUERY_SPLIT . ')\s*'; + /** @var string text block in SQL, single quited + * Note that does not include $$..$$ strings or anything with token name or nested ones + */ + private const PATTERN_TEXT_BLOCK_SINGLE_QUOTE = '(?:\'(?:[^\'\\\\]|\\\\.)*\')'; + /** @var string text block in SQL, dollar quoted + * NOTE: if this is added everything shifts by one lookup number + */ + private const PATTERN_TEXT_BLOCK_DOLLAR = '(?:\$(\w*)\$.*?\$\1\$)'; /** @var string comment regex - * anything that starts with -- and ends with a line break but any character that is not line break inbetween */ - private const PATTERN_COMMENT = '(?:\-\-[^\r\n]*?\r?\n)*\s*'; - /** @var string parts to ignore in the SQL */ - private const PATTERN_IGNORE = - // digit -> ignore - '\d+|' - // other string -> ignore - . '(?:\'.*?\')|'; - /** @var string named parameters */ - private const PATTERN_NAMED = '(:\w+)'; - /** @var string question mark parameters */ - private const PATTERN_QUESTION_MARK = '(?:(?:\?\?)?\s*(\?{1}))'; - /** @var string numbered parameters */ + * anything that starts with -- and ends with a line break but any character that is not line break inbetween + * this is the FIRST thing in the line and will skip any further lookups */ + private const PATTERN_COMMENT = '(?:\-\-[^\r\n]*?\r?\n)'; + // below are the params lookups + /** @var string named parameters, must start with single : */ + private const PATTERN_NAMED = '((? add line break to matches in "." . '/s'; + /** @var string lookup for only numbered placeholders */ + public const REGEX_LOOKUP_NUMBERED = '/' + . self::PATTERN_COMMENT . '|' + . self::PATTERN_TEXT_BLOCK_SINGLE_QUOTE . '|' + . self::PATTERN_TEXT_BLOCK_DOLLAR . '|' + // match for replace part + . '(?:' + // $n numbered part (\PG php) [1] + . self::PATTERN_NUMBERED + // end match + . ')' + . '/s'; + /** @var int position for regex in full placeholder lookup: named */ + public const LOOOKUP_NAMED_POS = 2; + /** @var int position for regex in full placeholder lookup: question mark */ + public const LOOOKUP_QUESTION_MARK_POS = 3; + /** @var int position for regex in full placeholder lookup: numbered */ + public const LOOOKUP_NUMBERED_POS = 4; + /** @var int matches position for replacement and single lookup */ + public const MATCHING_POS = 2; /** * Convert PDO type query with placeholders to \PG style and vica versa @@ -132,11 +133,12 @@ class ConvertPlaceholder $found = -1; } /** @var array 1: named */ - $named_matches = array_filter($matches[1]); + $named_matches = array_filter($matches[self::LOOOKUP_NAMED_POS]); /** @var array 2: open ? */ - $qmark_matches = array_filter($matches[2]); + $qmark_matches = array_filter($matches[self::LOOOKUP_QUESTION_MARK_POS]); /** @var array 3: $n matches */ - $numbered_matches = array_filter($matches[3]); + $numbered_matches = array_filter($matches[self::LOOOKUP_NUMBERED_POS]); + // print "**MATCHES**:
" . print_r($matches, true) . "
"; // count matches $count_named = count(array_unique($named_matches)); $count_qmark = count($qmark_matches); @@ -235,38 +237,37 @@ class ConvertPlaceholder $empty_params = $converted_placeholders['original']['empty_params']; switch ($converted_placeholders['type']) { case 'named': - // 0: full - // 0: full - // 1: pre part - // 2: keep part UNLESS '3' is set - // 3: replace part :named + // 1: replace part :named $pos = 0; $query_new = preg_replace_callback( self::REGEX_REPLACE_NAMED, function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) { - // only count up if $match[3] is not yet in lookup table - if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) { + if (!isset($matches[self::MATCHING_POS])) { + throw new \RuntimeException( + 'Cannot lookup ' . self::MATCHING_POS . ' in matches list', + 209 + ); + } + $match = $matches[self::MATCHING_POS]; + // only count up if $match[1] is not yet in lookup table + if (empty($params_lookup[$match])) { $pos++; - $params_lookup[$matches[3]] = '$' . $pos; + $params_lookup[$match] = '$' . $pos; // skip params setup if param list is empty if (!$empty_params) { - $params_new[] = $params[$matches[3]] ?? + $params_new[] = $params[$match] ?? throw new \RuntimeException( - 'Cannot lookup ' . $matches[3] . ' in params list', + 'Cannot lookup ' . $match . ' in params list', 210 ); } } // add the connectors back (1), and the data sets only if no replacement will be done - return $matches[1] . ( - empty($matches[3]) ? - $matches[2] : - $params_lookup[$matches[3]] ?? - throw new \RuntimeException( - 'Cannot lookup ' . $matches[3] . ' in params lookup list', - 211 - ) - ); + return $params_lookup[$match] ?? + throw new \RuntimeException( + 'Cannot lookup ' . $match . ' in params lookup list', + 211 + ); }, $converted_placeholders['original']['query'] ); @@ -276,61 +277,61 @@ class ConvertPlaceholder // order and data stays the same $params_new = $params ?? []; } - // 0: full - // 1: pre part - // 2: keep part UNLESS '3' is set - // 3: replace part ? + // 1: replace part ? $pos = 0; $query_new = preg_replace_callback( self::REGEX_REPLACE_QUESTION_MARK, function ($matches) use (&$pos, &$params_lookup) { + if (!isset($matches[self::MATCHING_POS])) { + throw new \RuntimeException( + 'Cannot lookup ' . self::MATCHING_POS . ' in matches list', + 229 + ); + } + $match = $matches[self::MATCHING_POS]; // only count pos up for actual replacements we will do - if (!empty($matches[3])) { + if (!empty($match)) { $pos++; $params_lookup[] = '$' . $pos; } // add the connectors back (1), and the data sets only if no replacement will be done - return $matches[1] . ( - empty($matches[3]) ? - $matches[2] : - '$' . $pos - ); + return '$' . $pos; }, $converted_placeholders['original']['query'] ); break; case 'numbered': - // 0: full - // 1: pre part - // 2: keep part UNLESS '3' is set - // 3: replace part $numbered + // 1: replace part $numbered $pos = 0; $query_new = preg_replace_callback( self::REGEX_REPLACE_NUMBERED, function ($matches) use (&$pos, &$params_new, &$params_lookup, $params, $empty_params) { - // only count up if $match[3] is not yet in lookup table - if (!empty($matches[3]) && empty($params_lookup[$matches[3]])) { + if (!isset($matches[self::MATCHING_POS])) { + throw new \RuntimeException( + 'Cannot lookup ' . self::MATCHING_POS . ' in matches list', + 239 + ); + } + $match = $matches[self::MATCHING_POS]; + // only count up if $match[1] is not yet in lookup table + if (empty($params_lookup[$match])) { $pos++; - $params_lookup[$matches[3]] = ':' . $pos . '_named'; + $params_lookup[$match] = ':' . $pos . '_named'; // skip params setup if param list is empty if (!$empty_params) { $params_new[] = $params[($pos - 1)] ?? throw new \RuntimeException( 'Cannot lookup ' . ($pos - 1) . ' in params list', - 220 + 230 ); } } // add the connectors back (1), and the data sets only if no replacement will be done - return $matches[1] . ( - empty($matches[3]) ? - $matches[2] : - $params_lookup[$matches[3]] ?? - throw new \RuntimeException( - 'Cannot lookup ' . $matches[3] . ' in params lookup list', - 221 - ) - ); + return $params_lookup[$match] ?? + throw new \RuntimeException( + 'Cannot lookup ' . $match . ' in params lookup list', + 231 + ); }, $converted_placeholders['original']['query'] ); diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Language/GetLocale.php b/www/vendor/egrajp/corelibs-composer-all/src/Language/GetLocale.php index d0e6f9e1..2953621b 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Language/GetLocale.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Language/GetLocale.php @@ -50,7 +50,6 @@ class GetLocale $locale = defined('SITE_LOCALE') && !empty(SITE_LOCALE) ? SITE_LOCALE : // else parse from default, if not 'en' - /** @phpstan-ignore-next-line DEFAULT_LOCALE could be empty */ (defined('DEFAULT_LOCALE') && !empty(DEFAULT_LOCALE) ? DEFAULT_LOCALE : 'en'); } @@ -97,8 +96,7 @@ class GetLocale $encoding = defined('SITE_ENCODING') && !empty(SITE_ENCODING) ? SITE_ENCODING : // or default encoding, if not 'UTF-8' - /** @phpstan-ignore-next-line DEFAULT_LOCALE could be empty */ - (defined('DEFAULT_ENCODING') && !empty(DEFAULT_ENCODING) ? + (defined('DEFAULT_ENCODING') ? DEFAULT_ENCODING : 'UTF-8'); } } diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Logging/Logging.php b/www/vendor/egrajp/corelibs-composer-all/src/Logging/Logging.php index d672d9a7..7476ef56 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Logging/Logging.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Logging/Logging.php @@ -30,6 +30,10 @@ class Logging { /** @var int minimum size for a max file size, so we don't set 1 byte, 10kb */ public const MIN_LOG_MAX_FILESIZE = 10 * 1024; + /** @var string log file extension, not changeable */ + private const LOG_FILE_NAME_EXT = "log"; + /** @var string log file block separator, not changeable */ + private const LOG_FILE_BLOCK_SEPARATOR = '.'; // NOTE: the second party array{} hs some errors /** @var array>|array{string:array{type:string,type_info?:string,mandatory:true,alias?:string,default:string|bool|Level,deprecated:bool,use?:string}} */ @@ -104,8 +108,6 @@ class Logging private string $log_folder = ''; /** @var string a alphanumeric name that has to be set as global definition */ private string $log_file_id = ''; - /** @var string log file name extension */ - private string $log_file_name_ext = 'log'; /** @var string log file name with folder, for actual writing */ private string $log_file_name = ''; /** @var int set in bytes */ @@ -431,7 +433,7 @@ class Logging private function buildLogFileName(Level $level, string $group_id = ''): string { // init base file path - $fn = $this->log_print_file . '.' . $this->log_file_name_ext; + $fn = $this->log_print_file . '.' . self::LOG_FILE_NAME_EXT; // log ID prefix settings, if not valid, replace with empty if (!empty($this->log_file_id)) { $rpl_string = $this->log_file_id; @@ -440,14 +442,15 @@ class Logging } $fn = str_replace('{LOGID}', $rpl_string, $fn); // log id (like a log file prefix) - $rpl_string = !$this->getLogFlag(Flag::per_level) ? '' : - '_' . $level->getName(); + $rpl_string = $this->getLogFlag(Flag::per_level) ? + self::LOG_FILE_BLOCK_SEPARATOR . $level->getName() : + ''; $fn = str_replace('{LEVEL}', $rpl_string, $fn); // create output filename // write per level - $rpl_string = !$this->getLogFlag(Flag::per_group) ? '' : + $rpl_string = $this->getLogFlag(Flag::per_group) ? // normalize level, replace all non alphanumeric characters with - - '_' . ( + self::LOG_FILE_BLOCK_SEPARATOR . ( // if return is only - then set error string preg_match( "/^-+$/", @@ -455,25 +458,29 @@ class Logging ) ? 'INVALID-LEVEL-STRING' : $level_string - ); + ) : + ''; $fn = str_replace('{GROUP}', $rpl_string, $fn); // create output filename // set per class, but don't use get_class as we will only get self - $rpl_string = !$this->getLogFlag(Flag::per_class) ? '' : '_' - // set sub class settings - . str_replace('\\', '-', Support::getCallerTopLevelClass()); + $rpl_string = $this->getLogFlag(Flag::per_class) ? + // set sub class settings + self::LOG_FILE_BLOCK_SEPARATOR . str_replace('\\', '-', Support::getCallerTopLevelClass()) : + ''; $fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename // if request to write to one file - $rpl_string = !$this->getLogFlag(Flag::per_page) ? - '' : - '_' . System::getPageName(System::NO_EXTENSION); + $rpl_string = $this->getLogFlag(Flag::per_page) ? + self::LOG_FILE_BLOCK_SEPARATOR . System::getPageName(System::NO_EXTENSION) : + ''; $fn = str_replace('{PAGENAME}', $rpl_string, $fn); // create output filename // if run id, we auto add ymd, so we ignore the log file date if ($this->getLogFlag(Flag::per_run)) { - $rpl_string = '_' . $this->getLogUniqueId(); // add 8 char unique string + // add 8 char unique string and date block with time + $rpl_string = self::LOG_FILE_BLOCK_SEPARATOR . $this->getLogUniqueId(); } elseif ($this->getLogFlag(Flag::per_date)) { - $rpl_string = '_' . $this->getLogDate(); // add date to file + // add date to file + $rpl_string = self::LOG_FILE_BLOCK_SEPARATOR . $this->getLogDate(); } else { $rpl_string = ''; } @@ -739,7 +746,10 @@ class Logging { if (empty($this->log_file_unique_id) || $override == true) { $this->log_file_unique_id = - date('Y-m-d_His') . '_U_' + date('Y-m-d_His') + . self::LOG_FILE_BLOCK_SEPARATOR + . 'U_' + // this doesn't have to be unique for everything, just for this logging purpose . substr(hash( 'sha1', random_bytes(63) diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php b/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php index 68e7a1df..b2262c70 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php @@ -1371,7 +1371,7 @@ class Generate ) { $this->msg .= sprintf( $this->l->__('Please enter a valid (%s) input for the %s Field!
'), - $this->dba->getTableArray()[$key]['error_example'], + $this->dba->getTableArray()[$key]['error_example'] ?? '[MISSING]', $this->dba->getTableArray()[$key]['output_name'] ); } @@ -2602,7 +2602,7 @@ class Generate } } // add lost error ones - $this->log->error('P: ' . $data['prefix'] . ', ' + $this->log->error('Prefix: ' . $data['prefix'] . ', ' . Support::prAr($_POST['ERROR'][$data['prefix']] ?? [])); if ($this->error && !empty($_POST['ERROR'][$data['prefix']])) { $prfx = $data['prefix']; // short diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/TableArrays/EditUsers.php b/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/TableArrays/EditUsers.php index c51dbd77..fce998ed 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/TableArrays/EditUsers.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/TableArrays/EditUsers.php @@ -50,7 +50,8 @@ class EditUsers implements Interface\TableArraysInterface 'HIDDEN_value' => $_POST['HIDDEN_password'] ?? '', 'CONFIRM_value' => $_POST['CONFIRM_password'] ?? '', 'output_name' => 'Password', - 'mandatory' => 1, + // make it not mandatory to create dummy accounts that can only login via login url id + 'mandatory' => 0, 'type' => 'password', // later has to be password for encryption in database 'update' => [ // connected field updates, and update data 'password_change_date' => [ // db row to update @@ -182,6 +183,7 @@ class EditUsers implements Interface\TableArraysInterface 'type' => 'text', 'error_check' => 'unique|custom', 'error_regex' => "/^[A-Za-z0-9]+$/", + 'error_example' => "ABCdef123", 'emptynull' => 1,'min_edit_acl' => '100', 'min_show_acl' => '100', ], diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Output/ProgressBar.php b/www/vendor/egrajp/corelibs-composer-all/src/Output/ProgressBar.php index 5c4f9c76..c64b6995 100644 --- a/www/vendor/egrajp/corelibs-composer-all/src/Output/ProgressBar.php +++ b/www/vendor/egrajp/corelibs-composer-all/src/Output/ProgressBar.php @@ -418,9 +418,7 @@ class ProgressBar // if this is percent, we ignore anything, it is auto positioned if ($this->label[$name]['type'] != 'percent') { foreach (['top', 'left', 'width', 'height'] as $pos_name) { - if ($$pos_name !== false) { - $this->label[$name][$pos_name] = intval($$pos_name); - } + $this->label[$name][$pos_name] = intval($$pos_name); } if ($align != '') { diff --git a/www/vendor/egrajp/corelibs-composer-all/test/configs/config.master.php b/www/vendor/egrajp/corelibs-composer-all/test/configs/config.master.php index 2bc50016..a54dbdc9 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/configs/config.master.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/configs/config.master.php @@ -183,8 +183,9 @@ list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null); define('HOST_NAME', $HOST_NAME); // BAIL ON MISSING MASTER SITE CONFIG if (!isset($SITE_CONFIG[HOST_NAME]['location'])) { - echo 'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator'; - exit; + throw new \InvalidArgumentException( + 'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator' + ); } // BAIL ON MISSING DB CONFIG: // we have either no db selction for this host but have db config entries @@ -200,8 +201,9 @@ if ( empty($DB_CONFIG[$SITE_CONFIG[HOST_NAME]['db_host']])) ) ) { - echo 'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator'; - exit; + throw new \InvalidArgumentException( + 'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator' + ); } // set SSL on $is_secure = false; diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/ACL/CoreLibsACLLoginTest.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/ACL/CoreLibsACLLoginTest.php index 1582a1ee..f29f02d7 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/ACL/CoreLibsACLLoginTest.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/ACL/CoreLibsACLLoginTest.php @@ -12,6 +12,8 @@ Not yet covered tests: - loginGetLocale - loginGetHeaderColor - loginGetPages +- loginGetPageLookupList +- loginPageAccessAllowed - loginGetEuid */ @@ -152,7 +154,6 @@ final class CoreLibsACLLoginTest extends TestCase // TARGET define('TARGET', 'test'); // LOGIN DB SCHEMA - // define('LOGIN_DB_SCHEMA', ''); // SHOULD SET // DEFAULT_ACL_LEVEL (d80) @@ -1531,6 +1532,12 @@ final class CoreLibsACLLoginTest extends TestCase $login_mock->loginGetEditAccessCuidFromUid($mock_settings['edit_access_uid']), 'Assert check access uid to cuid valid' ); + // - loginGetEditAccessCuidFromId + $this->assertEquals( + $expected['check_access_cuid'], + $login_mock->loginGetEditAccessCuidFromUid($mock_settings['edit_access_id']), + 'Assert check access id to cuid valid' + ); // Deprecated // - loginCheckEditAccess $this->assertEquals( diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedArrayHandlerTest.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedArrayHandlerTest.php index d320b845..e11aab8e 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedArrayHandlerTest.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedArrayHandlerTest.php @@ -1286,6 +1286,118 @@ final class CoreLibsCombinedArrayHandlerTest extends TestCase ) ); } + + /** + * provider for arrayModifyKey + * + * @return array> + */ + public function providerArrayModifyKey(): array + { + return [ + 'prefix and suffix add' => [ + 'array' => [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'foobar', + ], + 'prefix' => 'Prefix: ', + 'suffix' => '.suffix', + 'expected' => [ + 'Prefix: a.suffix' => 'foo', + 'Prefix: b.suffix' => 'bar', + 'Prefix: c.suffix' => 'foobar', + ], + ], + 'prefix add only' => [ + 'array' => [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'foobar', + ], + 'prefix' => 'Prefix: ', + 'suffix' => '', + 'expected' => [ + 'Prefix: a' => 'foo', + 'Prefix: b' => 'bar', + 'Prefix: c' => 'foobar', + ], + ], + 'suffix add only' => [ + 'array' => [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'foobar', + ], + 'prefix' => '', + 'suffix' => '.suffix', + 'expected' => [ + 'a.suffix' => 'foo', + 'b.suffix' => 'bar', + 'c.suffix' => 'foobar', + ], + ], + 'empty array' => [ + 'array' => [], + 'prefix' => '', + 'suffix' => '.suffix', + 'expected' => [], + ], + 'no suffix or prefix' => [ + 'array' => [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'foobar', + ], + 'prefix' => '', + 'suffix' => '', + 'expected' => [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'foobar', + ], + ], + 'integer index mixed' => [ + 'array' => [ + 'a' => 'foo', + 'b' => 'bar', + 3 => 'foobar', + ], + 'prefix' => '', + 'suffix' => '.suffix', + 'expected' => [ + 'a.suffix' => 'foo', + 'b.suffix' => 'bar', + '3.suffix' => 'foobar', + ], + ] + ]; + } + + /** + * Undocumented function + * + * @covers ::arrayModifyKey + * @dataProvider providerArrayModifyKey + * @testdox arrayModifyKey check that key is correctly modified with $key_mod_prefix and $key_mod_suffix [$_dataName] + * + * @param array $in_array + * @param string $key_mod_prefix + * @param string $key_mod_suffix + * @param array $expected + * @return void + */ + public function testArrayModifyKey( + array $in_array, + string $key_mod_prefix, + string $key_mod_suffix, + array $expected + ): void { + $this->assertEquals( + \CoreLibs\Combined\ArrayHandler::arrayModifyKey($in_array, $key_mod_prefix, $key_mod_suffix), + $expected + ); + } } // __END__ diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedDateTimeTest.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedDateTimeTest.php index d7efa9b7..1833f708 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedDateTimeTest.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Combined/CoreLibsCombinedDateTimeTest.php @@ -926,48 +926,114 @@ final class CoreLibsCombinedDateTimeTest extends TestCase public function daysIntervalProvider(): array { return [ - 'valid interval /, not named array' => [ - '2020/1/1', - '2020/1/30', - false, - [29, 22, 8], + // normal and format tests + 'valid interval / not named array' => [ + 'input_a' => '2020/1/1', + 'input_b' => '2020/1/30', + 'return_named' => false, // return_named + 'include_end_date' => true, // include_end_date + 'exclude_start_date' => false, // exclude_start_date + 'expected' => [30, 22, 8, false], ], - 'valid interval /, named array' => [ - '2020/1/1', - '2020/1/30', - true, - ['overall' => 29, 'weekday' => 22, 'weekend' => 8], + 'valid interval / named array' => [ + 'input_a' => '2020/1/1', + 'input_b' => '2020/1/30', + 'return_named' => true, + 'include_end_date' => true, + 'exclude_start_date' => false, + 'expected' => ['overall' => 30, 'weekday' => 22, 'weekend' => 8, 'reverse' => false], ], - 'valid interval -' => [ - '2020-1-1', - '2020-1-30', - false, - [29, 22, 8], - ], - 'valid interval switched' => [ - '2020/1/30', - '2020/1/1', - false, - [28, 0, 0], + 'valid interval with "-"' => [ + 'input_a' => '2020-1-1', + 'input_b' => '2020-1-30', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => false, + 'expected' => [30, 22, 8, false], ], 'valid interval with time' => [ - '2020/1/1 12:12:12', - '2020/1/30 13:13:13', - false, - [28, 21, 8], + 'input_a' => '2020/1/1 12:12:12', + 'input_b' => '2020/1/30 13:13:13', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => false, + 'expected' => [30, 22, 8, false], ], + // invalid 'invalid dates' => [ - 'abc', - 'xyz', - false, - [0, 0, 0] + 'input_a' => 'abc', + 'input_b' => 'xyz', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => false, + 'expected' => [0, 0, 0, false] ], - // this test will take a long imte + // this test will take a long time 'out of bound dates' => [ - '1900-1-1', - '9999-12-31', - false, - [2958463,2113189,845274], + 'input_a' => '1900-1-1', + 'input_b' => '9999-12-31', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => false, + 'expected' => [2958463, 2113189, 845274, false], + ], + // tests for include/exclude + 'exclude end date' => [ + 'input_b' => '2020/1/1', + 'input_a' => '2020/1/30', + 'return_named' => false, + 'include_end_date' => false, + 'exclude_start_date' => false, + 'expected' => [29, 21, 8, false], + ], + 'exclude start date' => [ + 'input_b' => '2020/1/1', + 'input_a' => '2020/1/30', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => true, + 'expected' => [29, 21, 8, false], + ], + 'exclude start and end date' => [ + 'input_b' => '2020/1/1', + 'input_a' => '2020/1/30', + 'return_named' => false, + 'include_end_date' => false, + 'exclude_start_date' => true, + 'expected' => [28, 20, 8, false], + ], + // reverse + 'reverse: valid interval' => [ + 'input_a' => '2020/1/30', + 'input_b' => '2020/1/1', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => false, + 'expected' => [30, 22, 8, true], + ], + 'reverse: exclude end date' => [ + 'input_a' => '2020/1/30', + 'input_b' => '2020/1/1', + 'return_named' => false, + 'include_end_date' => false, + 'exclude_start_date' => false, + 'expected' => [29, 21, 8, true], + ], + 'reverse: exclude start date' => [ + 'input_a' => '2020/1/30', + 'input_b' => '2020/1/1', + 'return_named' => false, + 'include_end_date' => true, + 'exclude_start_date' => true, + 'expected' => [29, 21, 8, true], + ], + 'reverse: exclude start and end date' => [ + 'input_a' => '2020/1/30', + 'input_b' => '2020/1/1', + 'return_named' => false, + 'include_end_date' => false, + 'exclude_start_date' => true, + 'expected' => [28, 20, 8, true], ], ]; } @@ -982,20 +1048,52 @@ final class CoreLibsCombinedDateTimeTest extends TestCase * * @param string $input_a * @param string $input_b - * @param bool $flag - * @param array $expected + * @param bool $return_named + * @param array $expected * @return void */ public function testCalcDaysInterval( string $input_a, string $input_b, - bool $flag, + bool $return_named, + bool $include_end_date, + bool $exclude_start_date, $expected ): void { $this->assertEquals( $expected, - \CoreLibs\Combined\DateTime::calcDaysInterval($input_a, $input_b, $flag) + \CoreLibs\Combined\DateTime::calcDaysInterval( + $input_a, + $input_b, + return_named:$return_named, + include_end_date:$include_end_date, + exclude_start_date:$exclude_start_date + ), + 'call calcDaysInterval' ); + if ($return_named) { + $this->assertEquals( + $expected, + \CoreLibs\Combined\DateTime::calcDaysIntervalNamedIndex( + $input_a, + $input_b, + include_end_date:$include_end_date, + exclude_start_date:$exclude_start_date + ), + 'call calcDaysIntervalNamedIndex' + ); + } else { + $this->assertEquals( + $expected, + \CoreLibs\Combined\DateTime::calcDaysIntervalNumIndex( + $input_a, + $input_b, + include_end_date:$include_end_date, + exclude_start_date:$exclude_start_date + ), + 'call calcDaysIntervalNamedIndex' + ); + } } /** @@ -1187,7 +1285,38 @@ final class CoreLibsCombinedDateTimeTest extends TestCase '2023-07-03', '2023-07-27', true - ] + ], + // reverse + 'reverse: no weekend' => [ + '2023-07-04', + '2023-07-03', + false + ], + 'reverse: start weekend sat' => [ + '2023-07-04', + '2023-07-01', + true + ], + 'reverse: start weekend sun' => [ + '2023-07-04', + '2023-07-02', + true + ], + 'reverse: end weekend sat' => [ + '2023-07-08', + '2023-07-03', + true + ], + 'reverse: end weekend sun' => [ + '2023-07-09', + '2023-07-03', + true + ], + 'reverse: long period > 6 days' => [ + '2023-07-27', + '2023-07-03', + true + ], ]; } diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Convert/CoreLibsConvertByteTest.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Convert/CoreLibsConvertByteTest.php index 95838889..0cd1682f 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Convert/CoreLibsConvertByteTest.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Convert/CoreLibsConvertByteTest.php @@ -40,7 +40,7 @@ final class CoreLibsConvertByteTest extends TestCase 4 => '1.00 KB', 5 => '1.02KiB', ], - 'invalud string number' => [ + 'invalid string number' => [ 0 => '1024 MB', 1 => '1024 MB', 2 => '1024 MB', diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Create/CoreLibsCreateHashTest.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Create/CoreLibsCreateHashTest.php index fcab739e..9ce36b35 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Create/CoreLibsCreateHashTest.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Create/CoreLibsCreateHashTest.php @@ -21,8 +21,10 @@ final class CoreLibsCreateHashTest extends TestCase public function hashData(): array { return [ - 'any string' => [ + 'hash tests' => [ + // this is the string 'text' => 'Some String Text', + // hash list special 'crc32b_reverse' => 'c5c21d91', // crc32b (in revere) 'sha1Short' => '4d2bc9ba0', // sha1Short // via hash @@ -31,6 +33,8 @@ final class CoreLibsCreateHashTest extends TestCase 'fnv132' => '9df444f9', // hash: fnv132 'fnv1a32' => '2c5f91b9', // hash: fnv1a32 'joaat' => '50dab846', // hash: joaat + 'ripemd160' => 'aeae3f041b20136451519edd9361570909300342', // hash: ripemd160, + 'sha256' => '9055080e022f224fa835929b80582b3c71c672206fa3a49a87412c25d9d42ceb', // hash: sha256 ] ]; } @@ -81,7 +85,7 @@ final class CoreLibsCreateHashTest extends TestCase { $list = []; foreach ($this->hashData() as $name => $values) { - foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat'] as $_hash_type) { + foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat', 'ripemd160', 'sha256'] as $_hash_type) { // default value test if ($_hash_type === null) { $hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT; @@ -114,6 +118,22 @@ final class CoreLibsCreateHashTest extends TestCase ]; } + /** + * Undocumented function + * + * @return array + */ + public function hashStandardProvider(): array + { + $hash_source = 'Some String Text'; + return [ + 'Long Hash check: ' . \CoreLibs\Create\Hash::STANDARD_HASH => [ + $hash_source, + hash(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source) + ], + ]; + } + /** * Undocumented function * @@ -136,9 +156,13 @@ final class CoreLibsCreateHashTest extends TestCase /** * Undocumented function * + * phpcs:disable Generic.Files.LineLength * @covers ::__sha1Short + * @covers ::__crc32b + * @covers ::sha1Short * @dataProvider sha1ShortProvider - * @testdox __sha1Short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName] + * @testdox __sha1Short/__crc32b/sha1short $input will be $expected (crc32b) and $expected_sha1 (sha1 short) [$_dataName] + * phpcs:enable Generic.Files.LineLength * * @param string $input * @param string $expected @@ -149,16 +173,29 @@ final class CoreLibsCreateHashTest extends TestCase // uses crc32b $this->assertEquals( $expected, - \CoreLibs\Create\Hash::__sha1Short($input) + \CoreLibs\Create\Hash::__sha1Short($input), + '__sha1Short depreacted' ); $this->assertEquals( $expected, - \CoreLibs\Create\Hash::__sha1Short($input, false) + \CoreLibs\Create\Hash::__sha1Short($input, false), + '__sha1Short (false) depreacted' + ); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::__crc32b($input), + '__crc32b' ); // sha1 type $this->assertEquals( $expected_sha1, - \CoreLibs\Create\Hash::__sha1Short($input, true) + \CoreLibs\Create\Hash::__sha1Short($input, true), + '__sha1Short (true) depreacted' + ); + $this->assertEquals( + $expected_sha1, + \CoreLibs\Create\Hash::sha1Short($input), + 'sha1Short' ); } @@ -166,8 +203,10 @@ final class CoreLibsCreateHashTest extends TestCase * Undocumented function * * @covers ::__hash + * @covers ::hashShort + * @covers ::hashShort * @dataProvider hashProvider - * @testdox __hash $input with $hash_type will be $expected [$_dataName] + * @testdox __hash/hashShort/hash $input with $hash_type will be $expected [$_dataName] * * @param string $input * @param string|null $hash_type @@ -179,12 +218,24 @@ final class CoreLibsCreateHashTest extends TestCase if ($hash_type === null) { $this->assertEquals( $expected, - \CoreLibs\Create\Hash::__hash($input) + \CoreLibs\Create\Hash::__hash($input), + '__hash' + ); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashShort($input), + 'hashShort' ); } else { $this->assertEquals( $expected, - \CoreLibs\Create\Hash::__hash($input, $hash_type) + \CoreLibs\Create\Hash::__hash($input, $hash_type), + '__hash with hash type' + ); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hash($input, $hash_type), + 'hash with hash type' ); } } @@ -193,8 +244,9 @@ final class CoreLibsCreateHashTest extends TestCase * Undocumented function * * @covers ::__hashLong + * @covers ::hashLong * @dataProvider hashLongProvider - * @testdox __hashLong $input will be $expected [$_dataName] + * @testdox __hashLong/hashLong $input will be $expected [$_dataName] * * @param string $input * @param string $expected @@ -206,6 +258,168 @@ final class CoreLibsCreateHashTest extends TestCase $expected, \CoreLibs\Create\Hash::__hashLong($input) ); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashLong($input) + ); + } + + /** + * Undocumented function + * + * @covers ::hash + * @covers ::hashStd + * @dataProvider hashStandardProvider + * @testdox hash/hashStd $input will be $expected [$_dataName] + * + * @param string $input + * @param string $expected + * @return void + */ + public function testHashStandard(string $input, string $expected): void + { + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashStd($input) + ); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hash($input) + ); + } + + /** + * Undocumented function + * + * @covers ::hash + * @testdox hash with invalid type + * + * @return void + */ + public function testInvalidHashType(): void + { + $hash_source = 'Some String Text'; + $expected = hash(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hash($hash_source, 'DOES_NOT_EXIST') + ); + } + + /** + * Note: this only tests default sha256 + * + * @covers ::hashHmac + * @testdox hash hmac test + * + * @return void + */ + public function testHashMac(): void + { + $hash_key = 'FIX KEY'; + $hash_source = 'Some String Text'; + $expected = '16479b3ef6fa44e1cdd8b2dcfaadf314d1a7763635e8738f1e7996d714d9b6bf'; + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key) + ); + } + + /** + * Undocumented function + * + * @covers ::hashHmac + * @testdox hash hmac with invalid type + * + * @return void + */ + public function testInvalidHashMacType(): void + { + $hash_key = 'FIX KEY'; + $hash_source = 'Some String Text'; + $expected = hash_hmac(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source, $hash_key); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key, 'DOES_NOT_EXIST') + ); + } + + /** + * Undocumented function + * + * @return array + */ + public function providerHashTypes(): array + { + return [ + 'Hash crc32b' => [ + 'crc32b', + true, + false, + ], + 'Hash adler32' => [ + 'adler32', + true, + false, + ], + 'HAsh fnv132' => [ + 'fnv132', + true, + false, + ], + 'Hash fnv1a32' => [ + 'fnv1a32', + true, + false, + ], + 'Hash: joaat' => [ + 'joaat', + true, + false, + ], + 'Hash: ripemd160' => [ + 'ripemd160', + true, + true, + ], + 'Hash: sha256' => [ + 'sha256', + true, + true, + ], + 'Hash: invalid' => [ + 'invalid', + false, + false + ] + ]; + } + + /** + * Undocumented function + * + * @covers ::isValidHashType + * @covers ::isValidHashHmacType + * @dataProvider providerHashTypes + * @testdox check if $hash_type is valid for hash $hash_ok and hash hmac $hash_hmac_ok [$_dataName] + * + * @param string $hash_type + * @param bool $hash_ok + * @param bool $hash_hmac_ok + * @return void + */ + public function testIsValidHashAndHashHmacTypes(string $hash_type, bool $hash_ok, bool $hash_hmac_ok): void + { + $this->assertEquals( + $hash_ok, + \CoreLibs\Create\Hash::isValidHashType($hash_type), + 'hash valid' + ); + $this->assertEquals( + $hash_hmac_ok, + \CoreLibs\Create\Hash::isValidHashHmacType($hash_type), + 'hash hmac valid' + ); } } diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/DB/CoreLibsDBIOTest.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/DB/CoreLibsDBIOTest.php index ac6314d6..f9e66c6a 100644 --- a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/DB/CoreLibsDBIOTest.php +++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/DB/CoreLibsDBIOTest.php @@ -135,6 +135,7 @@ final class CoreLibsDBIOTest extends TestCase } // check if they already exist, drop them if ($db->dbShowTableMetaData('table_with_primary_key') !== false) { + $db->dbExec("CREATE EXTENSION IF NOT EXISTS pgcrypto"); $db->dbExec("DROP TABLE table_with_primary_key"); $db->dbExec("DROP TABLE table_without_primary_key"); $db->dbExec("DROP TABLE test_meta"); @@ -3692,7 +3693,7 @@ final class CoreLibsDBIOTest extends TestCase * * @return array */ - public function preparedProviderValue(): array + public function providerDbGetPrepareCursorValue(): array { // 1: query (can be empty for do not set) // 2: stm name @@ -3736,7 +3737,7 @@ final class CoreLibsDBIOTest extends TestCase * test return prepare cursor errors * * @covers ::dbGetPrepareCursorValue - * @dataProvider preparedProviderValue + * @dataProvider providerDbGetPrepareCursorValue * @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName] * * @param string $query @@ -3769,6 +3770,94 @@ final class CoreLibsDBIOTest extends TestCase ); } + /** + * Undocumented function + * + * @return array + */ + public function providerDbPreparedCursorStatus(): array + { + return [ + 'empty statement pararm' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_a', + 'check_stm_name' => '', + 'check_query' => '', + 'expected' => false + ], + 'different stm_name' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_b', + 'check_stm_name' => 'other_name', + 'check_query' => '', + 'expected' => 0 + ], + 'same stm_name' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_c', + 'check_stm_name' => 'test_stm_c', + 'check_query' => '', + 'expected' => 1 + ], + 'same stm_name and query' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_d', + 'check_stm_name' => 'test_stm_d', + 'check_query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'expected' => 2 + ], + 'same stm_name and different query' => [ + 'query' => 'SELECT row_int, uid FROM table_with_primary_key', + 'stm_name' => 'test_stm_e', + 'check_stm_name' => 'test_stm_e', + 'check_query' => 'SELECT row_int, uid, row_int FROM table_with_primary_key', + 'expected' => 1 + ], + 'insert query test' => [ + 'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)', + 'stm_name' => 'test_stm_f', + 'check_stm_name' => 'test_stm_f', + 'check_query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)', + 'expected' => 2 + ] + ]; + } + + /** + * test cursor status for prepared statement + * + * @covers ::dbPreparedCursorStatus + * @dataProvider providerDbPreparedCursorStatus + * @testdox Check prepared $stm_name ($check_stm_name) status is $expected [$_dataName] + * + * @param string $query + * @param string $stm_name + * @param string $check_stm_name + * @param string $check_query + * @param bool|int $expected + * @return void + */ + public function testDbPreparedCursorStatus( + string $query, + string $stm_name, + string $check_stm_name, + string $check_query, + bool|int $expected + ): void { + $db = new \CoreLibs\DB\IO( + self::$db_config['valid'], + self::$log + ); + $db->dbPrepare($stm_name, $query); + // $db->dbExecute($stm_name); + $this->assertEquals( + $expected, + $db->dbPreparedCursorStatus($check_stm_name, $check_query), + 'check prepared stement cursor status' + ); + unset($db); + } + // - schema set/get tests // dbGetSchema, dbSetSchema @@ -4656,7 +4745,7 @@ final class CoreLibsDBIOTest extends TestCase $res = $db->dbReturnRowParams($query_select, ['CONVERT_TYPE_TEST']); // all hast to be string foreach ($res as $key => $value) { - $this->assertIsString($value, 'Aseert string for column: ' . $key); + $this->assertIsString($value, 'Assert string for column: ' . $key); } // convert base only $db->dbSetConvertFlag(Convert::on); @@ -4669,10 +4758,10 @@ final class CoreLibsDBIOTest extends TestCase } switch ($type_layout[$name]) { case 'int': - $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name); + $this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); break; default: - $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name); + $this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); break; } } @@ -4686,13 +4775,13 @@ final class CoreLibsDBIOTest extends TestCase } switch ($type_layout[$name]) { case 'int': - $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name); + $this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); break; case 'float': - $this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name); + $this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name); break; default: - $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name); + $this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); break; } } @@ -4706,17 +4795,17 @@ final class CoreLibsDBIOTest extends TestCase } switch ($type_layout[$name]) { case 'int': - $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name); + $this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); break; case 'float': - $this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name); + $this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name); break; case 'json': case 'jsonb': - $this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name); + $this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name); break; default: - $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name); + $this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); break; } } @@ -4730,25 +4819,25 @@ final class CoreLibsDBIOTest extends TestCase } switch ($type_layout[$name]) { case 'int': - $this->assertIsInt($value, 'Aseert int for column: ' . $key . '/' . $name); + $this->assertIsInt($value, 'Assert int for column: ' . $key . '/' . $name); break; case 'float': - $this->assertIsFloat($value, 'Aseert float for column: ' . $key . '/' . $name); + $this->assertIsFloat($value, 'Assert float for column: ' . $key . '/' . $name); break; case 'json': case 'jsonb': - $this->assertIsArray($value, 'Aseert array for column: ' . $key . '/' . $name); + $this->assertIsArray($value, 'Assert array for column: ' . $key . '/' . $name); break; case 'bytea': // for hex types it must not start with \x $this->assertStringStartsNotWith( '\x', $value, - 'Aseert bytes not starts with \x for column: ' . $key . '/' . $name + 'Assert bytes not starts with \x for column: ' . $key . '/' . $name ); break; default: - $this->assertIsString($value, 'Aseert string for column: ' . $key . '/' . $name); + $this->assertIsString($value, 'Assert string for column: ' . $key . '/' . $name); break; } } @@ -4920,8 +5009,8 @@ final class CoreLibsDBIOTest extends TestCase ) ), ($params === null ? - $db->dbGetQueryHash($query) : - $db->dbGetQueryHash($query, $params) + $db->dbBuildQueryHash($query) : + $db->dbBuildQueryHash($query, $params) ), 'Failed assertdbGetQueryHash ' ); @@ -5147,6 +5236,9 @@ final class CoreLibsDBIOTest extends TestCase $3 -- comment 3 , $4 + -- ignore $5, $6 + -- $7, $8 + -- digest($9, 10) ) SQL, 'count' => 4, @@ -5217,8 +5309,57 @@ final class CoreLibsDBIOTest extends TestCase SQL, 'count' => 2, 'convert' => false, + ], + // special $$ string case + 'text string, with $ placehoders that could be seen as $$ string' => [ + 'query' => << 6, + 'convert' => false, + ], + // NOTE, in SQL heredoc we cannot write $$ strings parts + 'text string, with $ placehoders are in $$ strings' => [ + 'query' => ' + SELECT row_int + FROM table_with_primary_key + WHERE + row_varchar = $$some string$$ OR + row_varchar = $tag$some string$tag$ OR + row_varchar = $btag$some $1 string$btag$ OR + row_varchar = $btag$some $1 $subtag$ something $subtag$string$btag$ OR + row_varchar = $1 + ', + 'count' => 1, + 'convert' => false, + ], + // a text string with escaped quite + 'text string, with escaped quote' => [ + 'query' => << 2, + 'convert' => false, ] ]; + $string = <<getLogUniqueId(); $this->assertMatchesRegularExpression( - "/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/", + "/^\d{4}-\d{2}-\d{2}_\d{6}\.U_[a-z0-9]{8}$/", $per_run_id, 'assert per log run id 1st' ); @@ -403,7 +403,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase $log->setLogUniqueId(true); $per_run_id_2nd = $log->getLogUniqueId(); $this->assertMatchesRegularExpression( - "/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/", + "/^\d{4}-\d{2}-\d{2}_\d{6}\.U_[a-z0-9]{8}$/", $per_run_id_2nd, 'assert per log run id 2nd' ); @@ -824,13 +824,13 @@ final class CoreLibsLoggingLoggingTest extends TestCase $this->assertTrue($log_ok, 'assert ::log (debug) OK'); $this->assertEquals( $log->getLogFile(), - $log->getLogFileId() . '_DEBUG.log' + $log->getLogFileId() . '.DEBUG.log' ); $log_ok = $log->log(Level::Info, 'INFO', group_id: 'GROUP_ID', prefix: 'PREFIX:'); $this->assertTrue($log_ok, 'assert ::log (info) OK'); $this->assertEquals( $log->getLogFile(), - $log->getLogFileId() . '_INFO.log' + $log->getLogFileId() . '.INFO.log' ); }