Compare commits

..

19 Commits

Author SHA1 Message Date
Clemens Schwaighofer
40e6444c2a CoreLibs update 2026-01-06 18:22:17 +09:00
Clemens Schwaighofer
4b015505ff admin libs update 2025-06-05 18:13:10 +09:00
Clemens Schwaighofer
e90387c1fc Composer update 2025-05-15 15:35:13 +09:00
Clemens Schwaighofer
3fb7169531 CoreLibs update 2025-01-16 10:25:19 +09:00
Clemens Schwaighofer
e4dd73d0e9 Composer package update 2024-12-18 10:38:34 +09:00
Clemens Schwaighofer
e71c53b887 Composer package update 2024-12-13 10:48:28 +09:00
Clemens Schwaighofer
16addc4f4b CoreLibs version update 2024-12-05 14:06:44 +09:00
Clemens Schwaighofer
7e845d3954 v9.22.0 update 2024-12-03 13:29:31 +09:00
Clemens Schwaighofer
6fcb7a44e0 Composer corelibs update 2024-11-27 14:36:02 +09:00
Clemens Schwaighofer
e82e4f6079 Admin pages update 2024-11-27 14:35:30 +09:00
Clemens Schwaighofer
231897cf5b phpstan 2.0 update 2024-11-18 18:33:45 +09:00
Clemens Schwaighofer
17da804073 Composer package update 2024-11-18 14:55:46 +09:00
Clemens Schwaighofer
96ad4b0f48 Update admin pages 2024-11-06 13:33:25 +09:00
Clemens Schwaighofer
1386afb552 Composer git pull update 2024-11-06 10:47:54 +09:00
Clemens Schwaighofer
86a9ad8789 Admin pages updates 2024-10-16 14:13:17 +09:00
Clemens Schwaighofer
0c4c018ffa Composer update 2024-09-20 13:39:21 +09:00
Clemens Schwaighofer
8b36807a2e admin files updates 2024-09-20 13:39:00 +09:00
Clemens Schwaighofer
8daef88e5e Composer dev update 2024-09-03 12:09:22 +09:00
Clemens Schwaighofer
a59fa7a2c9 Admin tests update 2024-09-03 12:08:37 +09:00
159 changed files with 12151 additions and 4348 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
composer.lock composer.lock
vendor/ vendor/
.env

View File

@@ -1,6 +1,8 @@
{ {
"require-dev": { "require-dev": {
"phpstan/phpstan": "^1.9", "phpstan/phpstan": "^2.0",
"phpstan/phpdoc-parser": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phan/phan": "^5.4", "phan/phan": "^5.4",
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9"
} }

743
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
<?php // phpcs:ignore PSR1.Files.SideEffects
declare(strict_types=1);
// url requests target test
require 'config.php';
use CoreLibs\Convert\Json;
$LOG_FILE_ID = 'classTest-urlrequests-target';
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
/**
* build return json
*
* @param array<string,mixed> $http_headers
* @param ?string $body
* @return string
*/
function buildContent(array $http_headers, ?string $body): string
{
if (is_string($body) && !empty($body)) {
$_body = Json::jsonConvertToArray($body);
if (Json::jsonGetLastError()) {
$body = [$body];
} else {
$body = $_body;
}
} elseif (is_string($body)) {
$body = [];
}
return Json::jsonConvertArrayTo([
'HEADERS' => $http_headers,
"REQUEST_TYPE" => $_SERVER['REQUEST_METHOD'],
"PARAMS" => $_GET,
"BODY" => $body,
// "STRING_BODY" => $body,
]);
}
$http_headers = array_filter($_SERVER, function ($value, $key) {
if (str_starts_with($key, 'HTTP_')) {
return true;
}
}, ARRAY_FILTER_USE_BOTH);
header("Content-Type: application/json; charset=UTF-8");
// if the header has Authorization and RunAuthTest then exit with 401
if (!empty($http_headers['HTTP_AUTHORIZATION']) && !empty($http_headers['HTTP_RUNAUTHTEST'])) {
header("HTTP/1.1 401 Unauthorized");
print buildContent($http_headers, '{"code": 401, "content": {"Error": "Not Authorized"}}');
exit(1);
}
// if server request type is get set file_get to null -> no body
if ($_SERVER['REQUEST_METHOD'] == "GET") {
$file_get = null;
} elseif (($file_get = file_get_contents('php://input')) === false) {
header("HTTP/1.1 404 Not Found");
print buildContent($http_headers, '{"code": 404, "content": {"Error": "file_get_contents failed"}}');
exit(1);
}
// str_replace('\"', '"', trim($file_get, '"'));
$log->debug('SERVER', $log->prAr($_SERVER));
$log->debug('HEADERS', $log->prAr($http_headers));
$log->debug('REQUEST TYPE', $_SERVER['REQUEST_METHOD']);
$log->debug('GET', $log->prAr($_GET));
$log->debug('POST', $log->prAr($_POST));
$log->debug('PHP-INPUT', $log->prAr($file_get));
print buildContent($http_headers, $file_get);
$log->debug('[END]', '=========================================>');
// __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -42,6 +42,20 @@ $backend = new CoreLibs\Admin\Backend(
$l10n, $l10n,
DEFAULT_ACL_LEVEL DEFAULT_ACL_LEVEL
); );
$login = new CoreLibs\ACL\Login(
$db,
$log,
$session,
[
'auto_login' => false,
'default_acl_level' => DEFAULT_ACL_LEVEL,
'logout_target' => '',
'site_locale' => SITE_LOCALE,
'site_domain' => SITE_DOMAIN,
'site_encoding' => SITE_ENCODING,
'locale_path' => BASE . INCLUDES . LOCALE,
]
);
use CoreLibs\Debug\Support; use CoreLibs\Debug\Support;
$PAGE_NAME = 'TEST CLASS: ADMIN BACKEND'; $PAGE_NAME = 'TEST CLASS: ADMIN BACKEND';
@@ -55,7 +69,45 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "SETACL[]: <br>"; print "SETACL[]: <br>";
$backend->setACL(['EMPTY' => 'EMPTY']); $backend->setACL(['EMPTY' => 'EMPTY']);
print "ADBEDITLOG: <br>"; print "ADBEDITLOG: <br>";
$backend->adbEditLog('CLASSTEST-ADMIN', 'Some info string'); $login->writeLog(
'CLASSTEST-ADMIN-BINARY',
'Some info string',
$backend->adbGetActionSet(),
write_type:'BINARY'
);
$login->writeLog(
'CLASSTEST-ADMIN-ZLIB',
'Some info string',
$backend->adbGetActionSet(),
write_type:'ZLIB'
);
$login->writeLog(
'CLASSTEST-ADMIN-SERIAL',
'Some info string',
$backend->adbGetActionSet(),
write_type:'SERIAL'
);
$login->writeLog(
'CLASSTEST-ADMIN-INVALID',
'Some info string',
$backend->adbGetActionSet(),
write_type:'INVALID'
);
// test with various
$backend->action = 'TEST ACTION';
$backend->action_id = 'TEST ACTION ID';
$backend->action_yes = 'TEST ACTION YES';
$backend->action_flag = 'TEST ACTION FLAG';
$backend->action_menu = 'TEST ACTION MENU';
$backend->action_loaded = 'TEST ACTION LOADED';
$backend->action_value = 'TEST ACTION VALUE';
$backend->action_type = 'TEST ACTION TYPE';
$backend->action_error = 'TEST ACTION ERROR';
$login->writeLog('CLASSTEST-ADMIN-JSON', [
"_GET" => $_GET,
"_POST" => $_POST,
], $backend->adbGetActionSet(), write_type:'JSON');
print "ADBTOPMENU(0): " . Support::printAr($backend->adbTopMenu(CONTENT_PATH)) . "<br>"; print "ADBTOPMENU(0): " . Support::printAr($backend->adbTopMenu(CONTENT_PATH)) . "<br>";
print "ADBMSG: <br>"; print "ADBMSG: <br>";
$backend->adbMsg('info', 'Message: %1$d', [1]); $backend->adbMsg('info', 'Message: %1$d', [1]);

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -51,6 +51,9 @@ $test_array = [
'element_c' => [ 'element_c' => [
'type' => 'email' 'type' => 'email'
], ],
'element_d' => [
'type' => 'butter'
],
], ],
]; ];
@@ -60,6 +63,8 @@ echo "ARRAYSEARCHRECURSIVE(email, [array], type): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array, 'type')) . "<br>"; . DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array, 'type')) . "<br>";
echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], type): " echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], type): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array['input'], 'type')) . "<br>"; . DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array['input'], 'type')) . "<br>";
echo "ARRAYSEARCHRECURSIVE(email, [array]['input'], wrong): "
. DgS::printAr(ArrayHandler::arraySearchRecursive('email', $test_array['input'], 'wrong')) . "<br>";
// all return // all return
echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): " echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): "
. Dgs::printAr((array)ArrayHandler::arraySearchRecursiveAll('email', $test_array, 'type')) . "<br>"; . Dgs::printAr((array)ArrayHandler::arraySearchRecursiveAll('email', $test_array, 'type')) . "<br>";
@@ -68,7 +73,15 @@ echo "ARRAYSEARCHRECURSIVEALL(email, [array], type): "
// simple search // simple search
echo "ARRAYSEARCHSIMPLE([array], type, email): " echo "ARRAYSEARCHSIMPLE([array], type, email): "
. (string)ArrayHandler::arraySearchSimple($test_array, 'type', 'email') . "<br>"; . Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', 'email')) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, not): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', 'not')) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, [email,butter]): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', ['email', 'butter'])) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, [email,not]): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', ['email', 'not'])) . "<br>";
echo "ARRAYSEARCHSIMPLE([array], type, [never,not]): "
. Dgs::prBl(ArrayHandler::arraySearchSimple($test_array, 'type', ['never', 'not'])) . "<br>";
$array_1 = [ $array_1 = [
'foo' => 'bar' 'foo' => 'bar'
@@ -115,9 +128,6 @@ print "ARRAYFLATFORKEY: " . DgS::printAr(ArrayHandler::arrayFlatForKey($test_arr
*/ */
function rec(string $pre, string $cur, array $node = []) function rec(string $pre, string $cur, array $node = [])
{ {
if (!is_array($node)) {
$node = [];
}
print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: " print "<div style='color: green;'>#### PRE: " . $pre . ", CUR: " . $cur . ", N-c: "
. count($node) . " [" . join('|', array_keys($node)) . "]</div>"; . count($node) . " [" . join('|', array_keys($node)) . "]</div>";
if (!$pre) { if (!$pre) {
@@ -171,6 +181,31 @@ $data = [
$search = ['image', 'result_image', 'nothing', 'EMPTY']; $search = ['image', 'result_image', 'nothing', 'EMPTY'];
$result = ArrayHandler::arraySearchKey($data, $search); $result = ArrayHandler::arraySearchKey($data, $search);
print "ARRAYSEARCHKEY: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>"; print "ARRAYSEARCHKEY: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
$result = ArrayHandler::arraySearchKey($data, $search, true);
print "ARRAYSEARCHKEY: FLAT: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
$result = ArrayHandler::arraySearchKey($data, $search, true, true);
print "ARRAYSEARCHKEY: FLAT:PREFIX: Search: " . DgS::printAr($search) . ", Found: " . DgS::printAr($result) . "<br>";
$result = ArrayHandler::arraySearchKey($data, ["EMPTY"], true);
print "ARRAYSEARCHKEY: FLAT:PREFIX: Search: " . DgS::printAr(["EMPTY"]) . ", Found: " . DgS::printAr($result) . "<br>";
// $data = [
// [
// [name] => qrc_apcd,
// [value] => 5834367225,
// ],
// [
// [name] => qrc_other,
// [value] => test,
// ],
// [
// [name] => qrc_car_type,
// [value] => T33P17,
// ],
// [
// [name] => qrc_deaer_store,
// [value] => 9990:001,
// ]
// ]
// $test = [ // $test = [
// 'A' => [ // 'A' => [
@@ -253,6 +288,246 @@ foreach (array_keys($array) as $search) {
} }
print "Key not exists: " . DgS::printAr(ArrayHandler::arrayGetNextKey($array, 'z')) . "<br>"; print "Key not exists: " . DgS::printAr(ArrayHandler::arrayGetNextKey($array, 'z')) . "<br>";
print "<hr>";
$keys = ['b', 'c', 'f'];
print "Return only: " . DgS::printAr($keys) . ": "
. DgS::printAr(ArrayHandler::arrayReturnMatchingKeyOnly($array, $keys)) . "<br>";
$out = array_filter($array, fn($key) => in_array($key, $keys), ARRAY_FILTER_USE_KEY);
print "array filter: " . DgS::printAr($keys) . ": " . DgS::printAr($out) . "<br>";
$out = array_intersect_key(
$array,
array_flip($keys)
);
print "array intersect key: " . DgS::printAr($keys) . ": " . DgS::printAr($out) . "<br>";
print "array + suffix: " . DgS::printAr(ArrayHandler::arrayModifyKey($array, key_mod_suffix:'_attached')) . "<br>";
print "<hr>";
$unsorted = [9, 5, 'A', 4, 'B', 6, 'c', 'C', 'a'];
$unsorted_keys = [
'A' => 9, 'B' => 5, 'C' => 'A', 'D' => 4, 'E' => 'B', 'F' => 6, 'G' => 'c',
'H1' => 'D', 'B1' => 'd', 'H' => 'C', 'I' => 'a'
];
print "Unsorted: " . DgS::printAr($unsorted) . "<br>";
print "(sort): " . DgS::printAr(ArrayHandler::sortArray($unsorted)) . "<br>";
print "(sort, lower): " . DgS::printAr(ArrayHandler::sortArray($unsorted, case_insensitive:true)) . "<br>";
print "(sort, reverse): " . DgS::printAr(ArrayHandler::sortArray($unsorted, reverse:true)) . "<br>";
print "(sort, lower, reverse): "
. DgS::printAr(ArrayHandler::sortArray($unsorted, case_insensitive:true, reverse:true)) . "<br>";
print "(sort, keys): " . DgS::printAr(ArrayHandler::sortArray($unsorted_keys, maintain_keys:true)) . "<br>";
print "(sort, keys, lower): "
. DgS::printAr(ArrayHandler::sortArray($unsorted_keys, maintain_keys:true, case_insensitive:true)) . "<br>";
print "<hr>";
$unsorted = [9 => 'A', 5 => 'B', 'A' => 'C', 4 => 'D', 'B' => 'E', 6 => 'F', 'c' => 'G', 'C' => 'H', 'a' => 'I'];
print "Unsorted Keys: " . DgS::printAr($unsorted) . "<br>";
print "(sort): " . DgS::printAr(ArrayHandler::sortArray($unsorted)) . "<br>";
print "(sort, keys): " . DgS::printAr(ArrayHandler::sortArray($unsorted, maintain_keys:true)) . "<br>";
print "(kosrt): " . DgS::printAr(ArrayHandler::ksortArray($unsorted)) . "<br>";
print "(kosrt, reverse): " . DgS::printAr(ArrayHandler::ksortArray($unsorted, reverse:true)) . "<br>";
print "(kosrt, lower case, reverse): "
. DgS::printAr(ArrayHandler::ksortArray($unsorted, case_insensitive:true, reverse:true)) . "<br>";
print "<hr>";
$nested = [
'B' => 'foo', 'a', '0', 9, /** @phpstan-ignore-line This is a test for wrong index */
'1' => ['z', 'b', 'a'],
'd' => ['zaip', 'bar', 'baz']
];
print "Nested: " . DgS::printAr($nested) . "<br>";
print "(sort): " . DgS::printAr(ArrayHandler::sortArray($nested)) . "<br>";
print "(ksort): " . DgS::printAr(ArrayHandler::ksortArray($nested)) . "<br>";
print "<hr>";
$search_array = [
'table_lookup' => [
'match' => [
['param' => 'access_d_cd', 'data' => 'a_cd', 'time_validation' => 'on_load',],
['param' => 'other_block', 'data' => 'b_cd'],
['pflaume' => 'other_block', 'data' => 'c_cd'],
['param' => 'third_block', 'data' => 'd_cd', 'time_validation' => 'cool'],
['special' => 'other_block', 'data' => 'e_cd', 'time_validation' => 'other'],
]
]
];
print "Search: " . DgS::printAr($search_array) . "<br>";
print "Result (all): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
$search_array,
'other_block',
'time_validation'
)) . "<br>";
print "Result (key): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
$search_array,
'other_block',
'time_validation',
'pflaume'
)) . "<br>";
print "Result (key): " . Dgs::printAr(ArrayHandler::findArraysMissingKey(
$search_array,
'other_block',
['data', 'time_validation'],
'pflaume'
)) . "<br>";
print "<hr>";
$search_array = [
'a' => [
'lookup' => 1,
'value' => 'Foo',
'other' => 'Bar',
],
'b' => [
'lookup' => 1,
'value' => 'AAA',
'other' => 'Other',
],
'c' => [
'lookup' => 0,
'value' => 'CCC',
'other' => 'OTHER',
],
'd' => [
'd-1' => [
'lookup' => 1,
'value' => 'D SUB 1',
'other' => 'Other B',
],
'd-2' => [
'lookup' => 0,
'value' => 'D SUB 2',
'other' => 'Other C',
],
'more' => [
'lookup' => 1,
'd-more-1' => [
'lookup' => 1,
'value' => 'D MORE SUB 1',
'other' => 'Other C',
],
'd-more-2' => [
'lookup' => 0,
'value' => 'D MORE SUB 0',
'other' => 'Other C',
],
]
]
];
print "Search: " . DgS::printAr($search_array) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
recursive:true
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
recursive:true,
flat_separator:'-=-'
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'lookup',
1,
recursive:true,
flat_result:false
)) . "<br>";
print "Result: " . DgS::printAr(ArrayHandler::selectArrayFromOption(
$search_array,
'other',
'Other',
case_insensitive:false,
)) . "<br>";
$nestedTestData = [
'level1_a' => [
'name' => 'Level1A',
'type' => 'parent',
'children' => [
'child1' => [
'name' => 'Child1',
'type' => 'child',
'active' => true
],
'child2' => [
'name' => 'Child2',
'type' => 'child',
'active' => false
]
]
],
'level1_b' => [
'name' => 'Level1B',
'type' => 'parent',
'children' => [
'child3' => [
'name' => 'Child3',
'type' => 'child',
'active' => true,
'nested' => [
'deep1' => [
'name' => 'Deep1',
'type' => 'deep',
'active' => true
]
]
]
]
],
'item5' => [
'name' => 'Direct',
'type' => 'child',
'active' => false
]
];
$result = ArrayHandler::selectArrayFromOption(
$nestedTestData,
'type',
'child',
false,
false,
true,
true,
':*'
);
print "*1*Result: " . DgS::printAr($result) . "<br>";
$data = [
'parent1' => [
'name' => 'Parent1',
'status' => 'ACTIVE',
'children' => [
'child1' => [
'name' => 'Child1',
'status' => 'active'
]
]
]
];
$result = ArrayHandler::selectArrayFromOption(
$data,
'status',
'active',
false, // not strict
true, // case insensitive
true, // recursive
true, // flat result
'|' // custom separator
);
print "*2*Result: " . DgS::printAr($result) . "<br>";
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
// basic class test file // basic class test file

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -74,9 +74,21 @@ foreach ($bytes as $byte) {
print '<div style="width: 35%; text-align: right; padding-right: 2px;">'; print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "(" . number_format($byte) . "/" . $byte . ") bytes :"; print "(" . number_format($byte) . "/" . $byte . ") bytes :";
$_bytes = Byte::humanReadableByteFormat($byte); $_bytes = Byte::humanReadableByteFormat($byte);
print '</div><div style="width: 10%;">' . $_bytes; print '</div>';
print '</div><div style="width: 10%;">'; print '<div style="width: 10%;">' . $_bytes . '</div>';
print Byte::stringByteFormat($_bytes); print '<div style="width: 40%;">';
try {
print Byte::stringByteFormat($_bytes);
} catch (\LengthException $e) {
print "LengthException 1: " . $e->getMessage();
try {
print "<br>S: " . Byte::stringByteFormat($_bytes, Byte::RETURN_AS_STRING);
} catch (\LengthException $e) {
print "LengthException 2: " . $e->getMessage();
} catch (\RuntimeException $e) {
print "RuntimeException 1: " . $e->getMessage();
}
}
print "</div>"; print "</div>";
// //
print "</div>"; print "</div>";
@@ -87,13 +99,85 @@ foreach ($bytes as $byte) {
print "bytes [si]:"; print "bytes [si]:";
$_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI); $_bytes = Byte::humanReadableByteFormat($byte, Byte::BYTE_FORMAT_SI);
print '</div><div style="width: 10%;">' . $_bytes; print '</div><div style="width: 10%;">' . $_bytes;
print '</div><div style="width: 10%;">'; print '</div><div style="width: 40%;">';
print Byte::stringByteFormat($_bytes); try {
print Byte::stringByteFormat($_bytes);
} catch (\LengthException $e) {
print "LengthException A: " . $e->getMessage();
try {
print "<br>Ssi: " . Byte::stringByteFormat($_bytes, Byte::RETURN_AS_STRING | Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "LengthException B: " . $e->getMessage();
} catch (\RuntimeException $e) {
print "RuntimeException A: " . $e->getMessage();
}
}
print "</div>"; print "</div>";
// //
print "</div>"; print "</div>";
} }
$string_bytes = [
'-117.42 MB',
'242.98 MB',
'254.78 MiB',
'1 EiB',
'8 EB',
'867.36EB',
'1000EB',
'10000EB',
];
print "<b>BYTE STRING TO BYTES TESTS</b><br>";
foreach ($string_bytes as $string) {
print '<div style="display: flex; border-bottom: 1px dashed gray;">';
//
print '<div style="width: 35%; text-align: right; padding-right: 2px;">';
print "string byte ($string) to bytes :";
try {
$_bytes = Byte::stringByteFormat($string);
} catch (\LengthException $e) {
print "<br>LengthException A: " . $e->getMessage();
$_bytes = 0;
}
try {
$_bytes_string = Byte::stringByteFormat($string, Byte::RETURN_AS_STRING);
} catch (\LengthException $e) {
print "<br>LengthException B: " . $e->getMessage();
$_bytes_string = '';
} catch (\RuntimeException $e) {
print "<br>RuntimeException: " . $e->getMessage();
$_bytes_string = '';
}
try {
$_bytes_si = Byte::stringByteFormat($string, Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "<br>LengthException A: " . $e->getMessage();
$_bytes_si = 0;
}
try {
$_bytes_string_si = Byte::stringByteFormat($string, Byte::RETURN_AS_STRING | Byte::BYTE_FORMAT_SI);
} catch (\LengthException $e) {
print "<br>LengthException B: " . $e->getMessage();
$_bytes_string_si = '';
} catch (\RuntimeException $e) {
print "<br>RuntimeException: " . $e->getMessage();
$_bytes_string_si = '';
}
print '</div>';
print '<div style="width: 20%;">'
. "F:" . number_format((int)$_bytes)
. '<br>B: ' . $_bytes
. '<br>S: ' . $_bytes_string
. "<br>Fsi:" . number_format((int)$_bytes_si)
. '<br>Bsi: ' . $_bytes_si
. '<br>Ssi: ' . $_bytes_string_si;
print '</div>';
print '<div style="width: 10%;">';
print "B: " . Byte::humanReadableByteFormat($_bytes) . "<br>";
print "Bsi: " . Byte::humanReadableByteFormat($_bytes_si, Byte::BYTE_FORMAT_SI);
print "</div>";
print "</div>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -18,7 +18,9 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-convert-colors'; $LOG_FILE_ID = 'classTest-convert-colors';
ob_end_flush(); ob_end_flush();
use CoreLibs\Convert\Colors; // use CoreLibs\Convert\Colors;
use CoreLibs\Convert\Color\Color;
use CoreLibs\Convert\Color\Coordinates;
use CoreLibs\Debug\Support as DgS; use CoreLibs\Debug\Support as DgS;
use CoreLibs\Convert\SetVarType; use CoreLibs\Convert\SetVarType;
@@ -27,7 +29,36 @@ $log = new CoreLibs\Logging\Logging([
'log_file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true, 'log_per_date' => true,
]); ]);
$color_class = 'CoreLibs\Convert\Colors';
/**
* print out a color block with info
*
* @param string $color
* @param string $text
* @param string $text_add
* @return string
*/
function display(string $color, string $text, string $text_add): string
{
$css = 'margin:5px;padding:50px;'
. 'width:10%;'
. 'text-align:center;'
. 'color:white;text-shadow: 0 0 5px black;font-weight:bold;';
$template = <<<HTML
<div style="background-color:{COLOR};{CSS}">
{TEXT}
</div>
HTML;
return str_replace(
["{COLOR}", "{TEXT}", "{CSS}"],
[
$color,
$text . (!empty($text_add) ? '<br>' . $text_add : ''),
$css
],
$template
);
}
$PAGE_NAME = 'TEST CLASS: CONVERT COLORS'; $PAGE_NAME = 'TEST CLASS: CONVERT COLORS';
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
@@ -36,32 +67,83 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>'; print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// out of bounds test
// define a list of from to color sets for conversion test // define a list of from to color sets for conversion test
$hwb = Color::hsbToHwb(new Coordinates\HSB([
160,
0,
50,
]));
print "HWB: " . DgS::printAr($hwb) . "<br>";
$hsb = Color::hwbToHsb($hwb);
print "HSB: " . DgS::printAr($hsb) . "<br>";
$oklch = Color::rgbToOkLch(Coordinates\RGB::create([
250,
0,
0
]));
print "OkLch: " . DgS::printAr($oklch) . "<br>";
$rgb = Color::okLchToRgb($oklch);
print "OkLch -> RGB: " . DgS::printAr($rgb) . "<br>";
$oklab = Color::rgbToOkLab(Coordinates\RGB::create([
250,
0,
0
]));
print "OkLab: " . DgS::printAr($oklab) . "<br>";
print display($oklab->toCssString(), $oklab->toCssString(), 'Oklab');
$rgb = Color::okLabToRgb($oklab);
print "OkLab -> RGB: " . DgS::printAr($rgb) . "<br>";
print display($rgb->toCssString(), $rgb->toCssString(), 'OkLab to RGB');
$rgb = Coordinates\RGB::create([250, 100, 10])->toLinear();
print "RGBlinear: " . DgS::printAr($rgb) . "<br>";
$rgb = Coordinates\RGB::create([0, 0, 0])->toLinear();
print "RGBlinear: " . DgS::printAr($rgb) . "<br>";
$cie_lab = Color::okLabToLab($oklab);
print "CieLab: " . DgS::printAr($cie_lab) . "<br>";
print display($cie_lab->toCssString(), $cie_lab->toCssString(), 'OkLab to Cie Lab');
$rgb = Coordinates\RGB::create([0, 0, 60]);
$hsb = Color::rgbToHsb($rgb);
$rgb_b = Color::hsbToRgb($hsb);
print "RGB: " . DgS::printAr($rgb) . "<br>";
print "RGB->HSB: " . DgS::printAr($hsb) . "<br>";
print "HSB->RGB: " . DgS::printAr($rgb_b) . "<br>";
$hsl = Coordinates\HSL::create([0, 20, 0]);
$hsb = Coordinates\HSB::create([0, 20, 0]);
$hsl_from_hsb = Color::hsbToHsl($hsb);
print "HSL from HSB: " . DgS::printAr($hsl_from_hsb) . "<br>";
print "<hr>";
// A(out of bounds) // A(out of bounds)
try { try {
print "C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: " print "C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: "
. CoreLibs\Convert\Colors::rgb2hex(-1, -1, -1) . "<br>"; . (new Coordinates\RGB([-1, -1, -1]))->returnAsHex() . "<br>";
} catch (\LengthException $e) { } catch (\LengthException $e) {
print "*Exception: " . $e->getMessage() . "<br>" . $e . "<br>"; print "*Exception: " . $e->getMessage() . "<br><pre>" . print_r($e, true) . "</pre><br>";
}
try {
print "\$C::S/COLOR invalid rgb->hex (gray 125): -1, -1, -1: "
. $color_class::rgb2hex(-1, -1, -1) . "<br>";
} catch (\LengthException $e) {
print "**Exception: " . $e->getMessage() . "<br><pre>" . print_r($e, true) . "</pre><br>";
} }
/* print "<hr>";
print "<h2>LEGACY</h2>";
// B(valid) // B(valid)
$rgb = [10, 20, 30]; $rgb = [50, 20, 30];
$hex = '#0a141e'; $hex = '#0a141e';
$hsb = [210, 67, 12]; $hsb = [210, 67, 12];
$hsb_f = [210.5, 67.5, 12.5]; $hsb_f = [210.5, 67.5, 12.5];
$hsl = [210, 50, 7.8]; $hsb = [210, 50, 7.8];
print "S::COLOR rgb->hex: $rgb[0], $rgb[1], $rgb[2]: " . Colors::rgb2hex($rgb[0], $rgb[1], $rgb[2]) . "<br>"; print "S::COLOR rgb->hex: $rgb[0], $rgb[1], $rgb[2]: " . Colors::rgb2hex($rgb[0], $rgb[1], $rgb[2]) . "<br>";
print "S::COLOR hex->rgb: $hex: " . DgS::printAr(SetVarType::setArray( print "S::COLOR hex->rgb: $hex: " . DgS::printAr(SetVarType::setArray(
Colors::hex2rgb($hex) Colors::hex2rgb($hex)
)) . "<br>"; )) . "<br>";
print "C::S/COLOR rgb->hext: $hex: " . DgS::printAr(SetVarType::setArray( print "C::S/COLOR rgb->hex: $hex: " . DgS::printAr(SetVarType::setArray(
CoreLibs\Convert\Colors::hex2rgb($hex) CoreLibs\Convert\Colors::hex2rgb($hex)
)) . "<br>"; )) . "<br>";
// C(to hsb/hsl) // C(to hsb/hsl)
@@ -82,16 +164,18 @@ print "S::COLOR hsb_f->rgb: $hsb_f[0], $hsb_f[1], $hsb_f[2]: "
. DgS::printAr(SetVarType::setArray( . DgS::printAr(SetVarType::setArray(
Colors::hsb2rgb($hsb_f[0], $hsb_f[1], $hsb_f[2]) Colors::hsb2rgb($hsb_f[0], $hsb_f[1], $hsb_f[2])
)) . "<br>"; )) . "<br>";
print "S::COLOR hsl->rgb: $hsl[0], $hsl[1], $hsl[2]: " print "S::COLOR hsl->rgb: $hsb[0], $hsb[1], $hsb[2]: "
. DgS::printAr(SetVarType::setArray( . DgS::printAr(SetVarType::setArray(
Colors::hsl2rgb($hsl[0], $hsl[1], $hsl[2]) Colors::hsl2rgb($hsb[0], $hsb[1], $hsb[2])
)) . "<br>"; )) . "<br>";
$hsb = [0, 0, 5]; $hsb = [0, 0, 5];
print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: " print "S::COLOR hsb->rgb: $hsb[0], $hsb[1], $hsb[2]: "
. DgS::printAr(SetVarType::setArray( . DgS::printAr(SetVarType::setArray(
Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2]) Colors::hsb2rgb($hsb[0], $hsb[1], $hsb[2])
)) . "<br>"; )) . "<br>"; */
print "<hr>";
// Random text // Random text
$h = rand(0, 359); $h = rand(0, 359);
@@ -99,10 +183,18 @@ $s = rand(15, 70);
$b = 100; $b = 100;
$l = 50; $l = 50;
print "RANDOM IN: H: " . $h . ", S: " . $s . ", B/L: " . $b . "/" . $l . "<br>"; print "RANDOM IN: H: " . $h . ", S: " . $s . ", B/L: " . $b . "/" . $l . "<br>";
print "RANDOM hsb->rgb: <pre>" . DgS::printAr(SetVarType::setArray(Colors::hsb2rgb($h, $s, $b))) . "</pre><br>"; print "RANDOM hsb->rgb: <pre>"
print "RANDOM hsl->rgb: <pre>" . DgS::printAr(SetVarType::setArray(Colors::hsl2rgb($h, $s, $l))) . "</pre><br>"; . DgS::printAr(SetVarType::setArray(Color::hsbToRgb(new Coordinates\HSB([$h, $s, $b])))) . "</pre><br>";
print "RANDOM hsl->rgb: <pre>"
. DgS::printAr(SetVarType::setArray(Color::hslToRgb(new Coordinates\HSL([$h, $s, $l])))) . "</pre><br>";
// TODO: run compare check input must match output print "<hr>";
$rgb = [0, 0, 0];
print "rgb 0,0,0: " . Dgs::printAr($rgb) . " => "
. Dgs::printAr(Color::rgbToHsb(new Coordinates\RGB([$rgb[0], $rgb[1], $rgb[2]]))) . "<br>";
print "<hr>";
print "</body></html>"; print "</body></html>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -268,7 +268,9 @@ foreach ($compare_datetimes as $compare_datetime) {
print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: " print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: "
. (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "<br>"; . (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "<br>";
} }
print "<hr>"; print "<hr>";
print "<h2>calcDaysInterval</h2>";
$compare_dates = [ $compare_dates = [
[ '2021-05-01', '2021-05-10', ], [ '2021-05-01', '2021-05-10', ],
[ '2021-05-10', '2021-05-01', ], [ '2021-05-10', '2021-05-01', ],
@@ -279,9 +281,21 @@ foreach ($compare_dates as $compare_date) {
print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: " print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: "
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "<br>"; . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "<br>";
print "CALCDAYSINTERVAL(named): $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)) . "<br>"; . DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1], return_named:true)) . "<br>";
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 "<hr>"; print "<hr>";
print "<h2>setWeekdayNameFromIsoDow</h2>";
// test date conversion // test date conversion
$dow = 2; $dow = 2;
print "DOW[$dow]: " . DateTime::setWeekdayNameFromIsoDow($dow) . "<br>"; print "DOW[$dow]: " . DateTime::setWeekdayNameFromIsoDow($dow) . "<br>";
@@ -297,26 +311,25 @@ $date = '2022-70-242';
print "DATE-dow[$date];invalid: " . DateTime::setWeekdayNameFromDate($date) . "<br>"; print "DATE-dow[$date];invalid: " . DateTime::setWeekdayNameFromDate($date) . "<br>";
print "DATE-dow[$date],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "<br>"; print "DATE-dow[$date],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "<br>";
print "DOW-date[$date];invalid: " . DateTime::setWeekdayNumberFromDate($date) . "<br>"; print "DOW-date[$date];invalid: " . DateTime::setWeekdayNumberFromDate($date) . "<br>";
print "<hr>";
// 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)) . "<br>";
$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)) . "<br>";
$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)) . "<br>";
$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)) . "<br>";
print "<hr>";
print "<h2>dateRangeHasWeekend</h2>";
// 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])) . "<br>";
}
print "</body></html>"; print "</body></html>";
@@ -460,7 +473,10 @@ function intervalStringFormatDeprecated(
// print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value) // print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value)
// . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "<br>"; // . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "<br>";
// var_dump($skip_last_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 ($part == 'f') {
if ($truncate_nanoseconds === true) { if ($truncate_nanoseconds === true) {
$value = round($value, 3); $value = round($value, 3);

View File

@@ -0,0 +1,265 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
// turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', true);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-db-convert-placeholder';
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,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$PAGE_NAME = 'TEST CLASS: DB CONVERT PLACEHOLDER';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "LOGFILE NAME: " . $log->getLogFile() . "<br>";
print "LOGFILE ID: " . $log->getLogFileId() . "<br>";
print "Lookup Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS) . "</pre>";
print "Lookup Numbered Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_LOOKUP_NUMBERED) . "</pre>";
print "Replace Named Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_NAMED) . "</pre>";
print "Replace Question Mark Regex: <pre>"
. Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_QUESTION_MARK) . "</pre>";
print "Replace Numbered Regex: <pre>" . Html::htmlent(ConvertPlaceholder::REGEX_REPLACE_NUMBERED) . "</pre>";
$uniqid = \CoreLibs\Create\Uids::uniqIdShort();
// $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: '');
// $binary_data = file_get_contents('class_test.db.php') ?: '';
$binary_data = '';
$params = [
$uniqid,
true,
'STRING A',
2,
2.5,
1,
date('H:m:s'),
date('Y-m-d H:i:s'),
json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]),
null,
'{"a", "b"}',
'{1,2}',
'{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}',
'("Text", 4, 6.3)',
$binary_data
];
$query = <<<SQL
INSERT INTO test_foo (
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1,
array_composite,
composite_item,
some_binary
) VALUES (
$1, $2, $3, $4, $5, $6,
$7, $8, $9, $10,
$11, $12,
$13,
$14,
$15
)
RETURNING
test_foo_id,
test, some_bool, string_a, number_a, number_a_numeric, smallint_a,
some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1,
array_composite,
composite_item,
some_binary
SQL;
print "<b>[ALL] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$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 "<b>[NO PARAMS] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT foo FROM bar WHERE baz = :baz AND buz = :baz AND biz = :biz AND boz = :bez";
$params = null;
print "<b>[NO PARAMS] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT row_varchar FROM table_with_primary_key WHERE row_varchar <> :row_varchar";
$params = null;
print "<b>[NO PARAMS] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = "SELECT row_varchar, row_varchar_literal, row_int, row_date FROM table_with_primary_key";
$params = null;
print "<b>[NO PARAMS] TEST</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = <<<SQL
UPDATE table_with_primary_key SET
row_int = $1::INT, row_numeric = $1::NUMERIC, row_varchar = $1
WHERE
row_varchar = $1
SQL;
$params = [1];
print "<b>[All the same params] TEST</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
$query = <<<SQL
SELECT row_varchar, row_varchar_literal, row_int, row_date
FROM table_with_primary_key
WHERE row_varchar = :row_varchar
SQL;
$params = [':row_varchar' => 1];
print "<b>[: param] TEST</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params))
. "<br>";
echo "<hr>";
print "<b>[P-CONV]</b>: "
. Support::printAr(
ConvertPlaceholder::updateParamList([
'original' => [
'query' => 'SELECT foo FROM bar WHERE baz = :baz AND buz = :biz AND biz = :biz AND boz = :bez',
'params' => [':baz' => 'SETBAZ', ':bez' => 'SETBEZ', ':biz' => 'SETBIZ'],
'empty_params' => false,
],
'type' => 'named',
'found' => 3,
// 'matches' => [
// ':baz'
// ],
// 'params_lookup' => [
// ':baz' => '$1'
// ],
// 'query' => "SELECT foo FROM bar WHERE baz = $1",
// 'parms' => [
// 'SETBAZ'
// ],
])
);
echo "<hr>";
// test connectors: = , <> () for query detection
// convert placeholder tests
// ? -> $n
// :name -> $n
// other way around (just visual)
$test_queries = [
'skip' => [
'query' => <<<SQL
SELECT test, string_a, number_a
FROM test_foo
SQL,
'params' => [],
'direction' => 'pg',
],
'numbers' => [
'query' => <<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE
foo = $1 AND bar = $1 AND foobar = $2
SQL,
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
'direction' => 'pdo',
],
'a?' => [
'query' => <<<SQL
INSERT INTO test_foo (
test, string_a, number_a
) VALUES (
?, ?, ?
)
SQL,
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
'direction' => 'pg',
],
'b?' => [
'query' => <<<SQL
SELECT test FROM test_foo = ?
SQL,
'params' => [1234],
'direction' => 'pg',
],
'b:' => [
'query' => <<<SQL
INSERT INTO test_foo (
test, string_a, number_a
) VALUES (
:test, :string_a, :number_a
)
SQL,
'params' => [
':test' => \CoreLibs\Create\Uids::uniqIdShort(),
':string_a' => 'string B-1',
':number_a' => 5678
],
'direction' => 'pg',
],
'select, compare $' => [
'query' => <<<SQL
SELECT row_varchar
FROM table_with_primary_key
WHERE
row_int >= $1 OR row_int <= $2 OR
row_int > $3 OR row_int < $4
OR row_int = $5 OR row_int <> $6
SQL,
'params' => null,
'direction' => 'pg'
]
];
foreach ($test_queries as $info => $data) {
$query = $data['query'];
$params = $data['params'];
$direction = $data['direction'];
print "<b>[$info] Convert</b>: "
. Support::printAr(ConvertPlaceholder::convertPlaceholderInQuery($query, $params, $direction))
. "<br>";
echo "<hr>";
}
print "</body></html>";
$log->debug('DEBUGEND', '==================================== [END]');
// __END__

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -70,8 +70,7 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
(is_array($res) ? "Array: Yes"
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -89,8 +88,7 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
(is_array($res) ? "Array: Yes"
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -108,8 +106,7 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
(is_array($res) ? "Array: Yes"
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -127,8 +124,7 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
(is_array($res) ? "Array: Yes"
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))
@@ -146,8 +142,7 @@ for ($i = 1; $i <= 6; $i++) {
print $i . ") " . $cache_flag . ": " print $i . ") " . $cache_flag . ": "
. "res: " . (is_bool($res) ? . "res: " . (is_bool($res) ?
"<b>Bool:</b> " . Support::prBl($res) : "<b>Bool:</b> " . Support::prBl($res) :
(is_array($res) ? "Array: Yes"
"Array: " . Support::prBl(is_array($res)) : '{-}')
) . ", " ) . ", "
. "cursor_ext: <pre>" . Support::printAr( . "cursor_ext: <pre>" . Support::printAr(
SetVarType::setArray($db->dbGetCursorExt($q_db_ret)) SetVarType::setArray($db->dbGetCursorExt($q_db_ret))

View File

@@ -0,0 +1,166 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
// turn on all error reporting
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', true);
// sample config
require 'config.php';
// for testing encryption compare
use OpenPGP\OpenPGP;
// define log file id
$LOG_FILE_ID = 'classTest-db-query-encryption';
ob_end_flush();
// use CoreLibs\Debug\Support;
use CoreLibs\Security\SymmetricEncryption;
use CoreLibs\Security\CreateKey;
use CoreLibs\Create\Hash;
use CoreLibs\Debug\Support;
$log = new CoreLibs\Logging\Logging([
'log_folder' => 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 "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// encryption key
$key_new = CreateKey::generateRandomKey();
print "Secret Key NEW: " . $key_new . "<br>";
// for reproducable test results
$key = 'e475c19b9a3c8363feb06b51f5b73f1dc9b6f20757d4ab89509bf5cc70ed30ec';
print "Secret Key: " . $key . "<br>";
// 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 . "<br>";
print "Encrypted: " . $encrypted . "<br>";
print "Hashed: " . $string_hashed . "<br>";
print "Hmac: " . $string_hmac . "<br>";
$db->dbExecParams(
<<<SQL
INSERT INTO test_encryption (
-- for compare
plain_text,
-- via php encryption
hash_text, hmac_text, crypt_text,
-- -- in DB encryption
pg_digest_bytea, pg_digest_text,
pg_hmac_bytea, pg_hmac_text,
pg_crypt_bytea, pg_crypt_text
) VALUES (
$1,
$2, $3, $4,
digest($1::VARCHAR, $5),
encode(digest($1, $5), 'hex'),
hmac($1, $6, $5),
encode(hmac($1, $6, $5), 'hex'),
pgp_sym_encrypt($1, $7),
encode(pgp_sym_encrypt($1, $7), 'hex')
) RETURNING cuuid
SQL,
[
// 1: original string
$text_string,
// 2: hashed, 3: hmac, 4: encrypted
$string_hashed, $string_hmac, $encrypted,
// 5: hash type, 6: hmac secret, 7: pgp secret
'sha256', $key, $key
]
);
$cuuid = $db->dbGetReturningExt('cuuid');
print "INSERTED: " . print_r($cuuid, true) . "<br>";
print "LAST ERROR: " . $db->dbGetLastError(true) . "<br>";
// read back
$res = $db->dbReturnRowParams(
<<<SQL
SELECT
-- for compare
plain_text,
-- via php encryption
hash_text, hmac_text, crypt_text,
-- in DB encryption
pg_digest_bytea, pg_digest_text,
pg_hmac_bytea, pg_hmac_text,
pg_crypt_bytea, pg_crypt_text,
encode(pg_crypt_bytea, 'hex') AS pg_crypt_bytea_hex,
pgp_sym_decrypt(pg_crypt_bytea, $2) AS from_pg_crypt_bytea,
pgp_sym_decrypt(decode(pg_crypt_text, 'hex'), $2) AS from_pg_crypt_text
FROM
test_encryption
WHERE
cuuid = $1
SQL,
[
$cuuid, $key
]
);
print "RES: <pre>" . Support::prAr($res) . "</pre><br>";
if ($res === false) {
echo "Failed to run query<br>";
} else {
if (hash_equals($string_hashed, $res['pg_digest_text'])) {
print "libsodium and pgcrypto hash match<br>";
}
if (hash_equals($string_hmac, $res['pg_hmac_text'])) {
print "libsodium and pgcrypto hash hmac match<br>";
}
// do compare for PHP and pgcrypto settings
$encryptedMessage_template = <<<TEXT
-----BEGIN PGP MESSAGE-----
{BASE64}
-----END PGP MESSAGE-----
TEXT;
$base64_string = base64_encode(hex2bin($res['pg_crypt_text']) ?: '');
$encryptedMessage = str_replace(
'{BASE64}',
$base64_string,
$encryptedMessage_template
);
try {
$literalMessage = OpenPGP::decryptMessage($encryptedMessage, passwords: [$key]);
$decrypted = $literalMessage->getLiteralData()->getData();
print "Pg decrypted PHP: " . $decrypted . "<br>";
if ($decrypted == $text_string) {
print "Decryption worked<br>";
}
} catch (\Exception $e) {
print "Error decrypting message: " . $e->getMessage() . "<br>";
}
}
print "</body></html>";
// __END__

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -76,41 +76,41 @@ $db->dbResetEncoding();
// empty calls, none of the below should fail // 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(); $foo = $db->dbGetReturningExt();
$db->dbGetReturningExt('foo'); $foo = $db->dbGetReturningExt('foo');
$db->dbGetReturningExt('foo', 0); $foo = $db->dbGetReturningExt('foo', 0);
$db->dbGetReturningExt(pos: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); $foo = $db->dbGetFieldType(0);
$db->dbGetFieldType('foo'); $foo = $db->dbGetFieldType('foo');
// //
$db->dbGetPrepareCursorValue('foo', 'bar'); $foo = $db->dbGetPrepareCursorValue('foo', 'bar');
// TEST CACHE READS // TEST CACHE READS
@@ -228,7 +228,7 @@ print "RETURN ROW PARAMS: " . print_r(
$db->dbPrepare("ins_test_foo", "INSERT INTO test_foo (test) VALUES ($1) RETURNING test"); $db->dbPrepare("ins_test_foo", "INSERT INTO test_foo (test) VALUES ($1) RETURNING test");
$status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]); $status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]);
print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status) . " |<br>" print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status) . " |<br>"
. "QUERY: " . $db->dbGetPrepareCursorValue('ins_test_foo', 'query') . " |<br>" . "QUERY: " . Support::printToString($db->dbGetPrepareCursorValue('ins_test_foo', 'query')) . " |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | "
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
. "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>"; . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>";
@@ -239,7 +239,7 @@ print "PREPARE INSERT PREVIOUS INSERTED: "
print "PREPARE CURSOR RETURN:<br>"; print "PREPARE CURSOR RETURN:<br>";
foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) { foreach (['pk_name', 'count', 'query', 'returning_id'] as $key) {
print "KEY: " . $key . ': ' . $db->dbGetPrepareCursorValue('ins_test_foo', $key) . "<br>"; print "KEY: " . $key . ': ' . Support::prAr($db->dbGetPrepareCursorValue('ins_test_foo', $key)) . "<br>";
} }
$query = <<<SQL $query = <<<SQL
@@ -255,7 +255,7 @@ SQL;
$db->dbPrepare("ins_test_foo_eom", $query); $db->dbPrepare("ins_test_foo_eom", $query);
$status = $db->dbExecute("ins_test_foo_eom", ['EOM BAR TEST ' . time()]); $status = $db->dbExecute("ins_test_foo_eom", ['EOM BAR TEST ' . time()]);
print "EOM STRING PREPARE INSERT[ins_test_foo_eom] STATUS: " . Support::printToString($status) . " |<br>" print "EOM STRING PREPARE INSERT[ins_test_foo_eom] STATUS: " . Support::printToString($status) . " |<br>"
. "QUERY: " . $db->dbGetPrepareCursorValue('ins_test_foo_eom', 'query') . " |<br>" . "QUERY: " . Support::printToString($db->dbGetPrepareCursorValue('ins_test_foo_eom', 'query')) . " |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | "
. "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | "
. "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>"; . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "<br>";
@@ -273,8 +273,8 @@ $query_insert = <<<SQL
INSERT INTO INSERT INTO
test_foo test_foo
( (
test, some_bool, string_a, number_a, number_a_numeric, test, some_bool, string_a, number_a, numeric_a,
some_time, some_timestamp, json_string some_internval, some_timestamp, json_string
) VALUES ( ) VALUES (
$1, $2, $3, $4, $5, $1, $2, $3, $4, $5,
$6, $7, $8 $6, $7, $8
@@ -283,8 +283,8 @@ RETURNING test
SQL; SQL;
$query_select = <<<SQL $query_select = <<<SQL
SELECT SELECT
test, some_bool, string_a, number_a, number_a_numeric, test, some_bool, string_a, number_a, numeric_a,
some_time, some_time, some_timestamp, json_string some_time, some_internval, some_timestamp, json_string
FROM FROM
test_foo test_foo
WHERE WHERE
@@ -316,7 +316,8 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
$db->dbReturnRowParams( $db->dbReturnRowParams(
$query_select, $query_select,
[$__last_insert_id] [$__last_insert_id]
) ),
true
) . "<br>"; ) . "<br>";
// B // B
$status = $db->dbExecParams( $status = $db->dbExecParams(
@@ -345,7 +346,8 @@ print "EOM STRING EXEC RETURN TEST: " . print_r(
$db->dbReturnRowParams( $db->dbReturnRowParams(
$query_select, $query_select,
[$__last_insert_id] [$__last_insert_id]
) ),
true
) . "<br>"; ) . "<br>";
// params > 10 for debug // params > 10 for debug
// error catcher // error catcher
@@ -552,7 +554,7 @@ print "<b>PREPARE QUERIES</b><br>";
// READ PREPARE // READ PREPARE
$q_prep = <<<SQL $q_prep = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a, SELECT test_foo_id, test, some_bool, string_a, number_a,
number_a_numeric, some_time numeric_a, some_time
FROM test_foo FROM test_foo
WHERE test = $1 WHERE test = $1
ORDER BY test_foo_id DESC LIMIT 5 ORDER BY test_foo_id DESC LIMIT 5
@@ -580,7 +582,7 @@ if ($db->dbPrepare('sel_test_foo', $q_prep) === false) {
// sel test with ANY () type // sel test with ANY () type
$q_prep = "SELECT test_foo_id, test, some_bool, string_a, number_a, " $q_prep = "SELECT test_foo_id, test, some_bool, string_a, number_a, "
. "number_a_numeric, some_time " . "numeric_a, some_time "
. "FROM test_foo " . "FROM test_foo "
. "WHERE test = ANY($1) " . "WHERE test = ANY($1) "
. "ORDER BY test_foo_id DESC LIMIT 5"; . "ORDER BY test_foo_id DESC LIMIT 5";
@@ -616,7 +618,7 @@ $test_bar = $db->dbEscapeLiteral('SOMETHING DIFFERENT');
$q = <<<SQL $q = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a, SELECT test_foo_id, test, some_bool, string_a, number_a,
-- comment -- comment
number_a_numeric, some_time numeric_a, some_time
FROM test_foo FROM test_foo
WHERE test = $test_bar WHERE test = $test_bar
ORDER BY test_foo_id DESC LIMIT 5 ORDER BY test_foo_id DESC LIMIT 5
@@ -629,7 +631,7 @@ print "DB RETURN PARAMS<br>";
$q = <<<SQL $q = <<<SQL
SELECT test_foo_id, test, some_bool, string_a, number_a, SELECT test_foo_id, test, some_bool, string_a, number_a,
-- comment -- comment
number_a_numeric, some_time numeric_a, some_time
FROM test_foo FROM test_foo
WHERE test = $1 WHERE test = $1
ORDER BY test_foo_id DESC LIMIT 5 ORDER BY test_foo_id DESC LIMIT 5
@@ -644,7 +646,7 @@ echo "<hr>";
print "DB RETURN PARAMS LIKE<br>"; print "DB RETURN PARAMS LIKE<br>";
$q = <<<SQL $q = <<<SQL
SELECT SELECT
test_foo_id, test, some_bool, string_a, number_a, number_a_numeric test_foo_id, test, some_bool, string_a, number_a, numeric_a
FROM test_foo FROM test_foo
WHERE string_a LIKE $1; WHERE string_a LIKE $1;
SQL; SQL;
@@ -658,7 +660,7 @@ echo "<hr>";
print "DB RETURN PARAMS ANY<br>"; print "DB RETURN PARAMS ANY<br>";
$q = <<<SQL $q = <<<SQL
SELECT SELECT
test_foo_id, test, some_bool, string_a, number_a, number_a_numeric test_foo_id, test, some_bool, string_a, number_a, numeric_a
FROM test_foo FROM test_foo
WHERE string_a = ANY($1); WHERE string_a = ANY($1);
SQL; SQL;
@@ -674,7 +676,7 @@ echo "<hr>";
print "COMPOSITE ELEMENT READ<br>"; print "COMPOSITE ELEMENT READ<br>";
$res = $db->dbReturnRow("SELECT item, count, (item).name, (item).price, (item).supplier_id FROM on_hand"); $res = $db->dbReturnRow("SELECT item, count, (item).name, (item).price, (item).supplier_id FROM on_hand");
print "ROW: <pre>" . print_r($res) . "</pre>"; print "ROW: <pre>" . print_r($res, true) . "</pre>";
var_dump($res); var_dump($res);
print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>"; print "Field Name/Types: <pre>" . print_r($db->dbGetFieldNameTypes(), true) . "</pre>";
echo "<hr>"; echo "<hr>";
@@ -705,6 +707,17 @@ if (
} else { } else {
print "[PGB] [3] pgb_sel_test_foo prepare OK<br>"; print "[PGB] [3] pgb_sel_test_foo prepare OK<br>";
} }
$stm_status = $db->dbPreparedCursorStatus('');
print "[PGB] Empty statement name: " . $log->prAr($stm_status) . "<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foobar');
print "[PGB] Prepared name not match status: $stm_status<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo');
print "[PGB] Prepared name match status: $stm_status<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', $q_prep);
print "[PGB] prepared exists and query match status: $stm_status<br>";
$stm_status = $db->dbPreparedCursorStatus('pgb_sel_test_foo', "SELECT * FROM test_foo");
print "[PGB] prepared exists and query not match status: $stm_status<br>";
$db_pgb->dbClose(); $db_pgb->dbClose();
# db write class test # db write class test

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -53,6 +53,9 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) {
} else { } else {
print "NO DB HANDLER<br>"; print "NO DB HANDLER<br>";
} }
// REGEX for placeholder count
print "Placeholder lookup regex: <pre>" . CoreLibs\DB\Support\ConvertPlaceholder::REGEX_LOOKUP_NUMBERED . "</pre>";
// turn on debug replace for placeholders // turn on debug replace for placeholders
$db->dbSetDebugReplacePlaceholder(true); $db->dbSetDebugReplacePlaceholder(true);
@@ -62,59 +65,136 @@ $db->dbExec("TRUNCATE test_foo");
$uniqid = \CoreLibs\Create\Uids::uniqIdShort(); $uniqid = \CoreLibs\Create\Uids::uniqIdShort();
$binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: ''); $binary_data = $db->dbEscapeBytea(file_get_contents('class_test.db.php') ?: '');
$query_params = [ $query_params = [
$uniqid, $uniqid, // test
true, true, // some_bool
'STRING A', 'STRING A', // string_a
2, 2, // number_a
2.5, 2.5, // numeric_a
1, 1, // smallint
date('H:m:s'), date('H:m:s'), // some_internval
date('Y-m-d H:i:s'), date('Y-m-d H:i:s'), // some_timestamp
json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]), json_encode(['a' => 'string', 'b' => 1, 'c' => 1.5, 'f' => true, 'g' => ['a', 1, 1.5]]), // json_string
null, null, // null_var
'{"a", "b"}', '{"a", "b"}', // array_char_1
'{1,2}', '{1,2}', // array_int_1
'{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}', '{"(array Text A, 5, 8.8)","(array Text B, 10, 15.2)"}', // array_composite
'("Text", 4, 6.3)', '("Text", 4, 6.3)', // composite_item
$binary_data $binary_data, // some_binary
date('Y-m-d'), // some_date
date('H:i:s'), // some_time
'{"c", "d", "e"}', // array_char_2
'{3,4,5}', // array_int_2
12345667778818, // bigint
1.56, // numbrer_real
3.75, // number_double
124.5, // numeric_3
\CoreLibs\Create\Uids::uuidv4() // uuid_var
]; ];
$query_insert = <<<SQL $query_insert = <<<SQL
INSERT INTO test_foo ( INSERT INTO test_foo (
test, some_bool, string_a, number_a, number_a_numeric, smallint_a, -- row 1
some_time, some_timestamp, json_string, null_var, test, some_bool, string_a, number_a, numeric_a, smallint_a,
-- row 2
some_internval, some_timestamp, json_string, null_var,
-- row 3
array_char_1, array_int_1, array_char_1, array_int_1,
-- row 4
array_composite, array_composite,
-- row 5
composite_item, composite_item,
some_binary -- row 6
some_binary,
-- row 7
some_date, some_time,
-- row 8
array_char_2, array_int_2,
-- row 9
bigint_a, number_real, number_double, numeric_3,
-- row 10
uuid_var
) VALUES ( ) VALUES (
-- row 1
$1, $2, $3, $4, $5, $6, $1, $2, $3, $4, $5, $6,
-- row 2
$7, $8, $9, $10, $7, $8, $9, $10,
-- row 3
$11, $12, $11, $12,
-- row 4
$13, $13,
-- row 5
$14, $14,
$15 -- row 6
$15,
-- row 7
$16, $17,
-- row 8
$18, $19,
-- row 9
$20, $21, $22, $23,
-- row 10
$24
) )
RETURNING RETURNING
test_foo_id, test_foo_id, number_serial, identity_always, identitiy_default, default_uuid,
test, some_bool, string_a, number_a, number_a_numeric, smallint_a, test, some_bool, string_a, number_a, numeric_a, smallint_a,
some_time, some_timestamp, json_string, null_var, some_internval, some_timestamp, json_string, null_var,
array_char_1, array_int_1, array_char_1, array_int_1,
array_composite, array_composite,
composite_item, composite_item,
some_binary some_binary,
some_date,
array_char_2, array_int_2,
bigint_a, number_real, number_double, numeric_3,
uuid_var
SQL; SQL;
print "Placeholders: <pre>" . print_r($db->dbGetQueryParamPlaceholders($query_insert), true) . "<pre>";
$status = $db->dbExecParams($query_insert, $query_params); $status = $db->dbExecParams($query_insert, $query_params);
echo "<b>*</b><br>"; echo "<b>*</b><br>";
echo "INSERT ALL COLUMN TYPES: " echo "INSERT ALL COLUMN TYPES: "
. Support::printToString($query_params) . " |<br>" . Support::printToString($query_params) . " |<br>"
. "QUERY: " . $db->dbGetQuery() . " |<br>" . "QUERY: <pre>" . $db->dbGetQuery() . "</pre> |<br>"
. "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " |<br>" . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " |<br>"
. "RETURNING EXT: <pre>" . print_r($db->dbGetReturningExt(), true) . "</pre> |<br>" . "RETURNING EXT: <pre>" . print_r($db->dbGetReturningExt(), true) . "</pre> |<br>"
. "RETURNING RETURN: <pre>" . print_r($db->dbGetReturningArray(), true) . "<pre> |<br>" . "RETURNING RETURN: <pre>" . print_r($db->dbGetReturningArray(), true) . "<pre> |<br>"
. "ERROR: " . $db->dbGetLastError(true) . "<br>"; . "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>"; echo "<hr>";
print "<b>ANY call</b><br>";
$query = <<<SQL
SELECT test
FROM test_foo
WHERE string_a = ANY($1)
SQL;
$query_value = '{'
. join(',', ['STRING A'])
. '}';
while (is_array($res = $db->dbReturnParams($query, [$query_value]))) {
print "Result: " . Support::prAr($res) . "<br>";
}
echo "<hr>";
echo "<b>CASE part</b><br>";
$query = <<<SQL
UPDATE
test_foo
SET
some_timestamp = NOW(),
-- if not 1 set, else keep at one
smallint_a = (CASE
WHEN smallint_a <> 1 THEN $1
ELSE 1::INT
END)::INT
WHERE
string_a = $2
SQL;
echo "QUERY: <pre>" . $query . "</pre>";
$res = $db->dbExecParams($query, [1, 'foobar']);
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>";
// test connectors: = , <> () for query detection // test connectors: = , <> () for query detection
// convert placeholder tests // convert placeholder tests
@@ -131,6 +211,16 @@ SQL,
'params' => [], 'params' => [],
'direction' => 'pg', 'direction' => 'pg',
], ],
'numbers' => [
'query' => <<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE
foo = $1 AND bar = $1 AND foobar = $2
SQL,
'params' => [\CoreLibs\Create\Uids::uniqIdShort(), 'string A-1', 1234],
'direction' => 'pdo',
],
'a?' => [ 'a?' => [
'query' => <<<SQL 'query' => <<<SQL
INSERT INTO test_foo ( INSERT INTO test_foo (
@@ -157,6 +247,18 @@ SQL,
], ],
'direction' => 'pg', 'direction' => 'pg',
], ],
'select, compare $' => [
'query' => <<<SQL
SELECT string_a
FROM test_foo
WHERE
number_a >= $1 OR number_a <= $2 OR
number_a > $3 OR number_a < $4
OR number_a = $5 OR number_a <> $6
SQL,
'params' => [1, 2, 3, 4, 5, 6],
'direction' => 'pg'
],
]; ];
$db->dbSetConvertPlaceholder(true); $db->dbSetConvertPlaceholder(true);
@@ -169,11 +271,12 @@ foreach ($test_queries as $info => $data) {
// . "<br>"; // . "<br>";
if ($db->dbCheckQueryForSelect($query)) { if ($db->dbCheckQueryForSelect($query)) {
$row = $db->dbReturnRowParams($query, $params); $row = $db->dbReturnRowParams($query, $params);
print "[$info] SELECT: " . Support::prAr($row) . "<br>"; print "<b>[$info]</b> SELECT: " . Support::prAr($row) . "<br>";
} else { } else {
$db->dbExecParams($query, $params); $db->dbExecParams($query, $params);
} }
print "[$info] " . Support::printAr($db->dbGetPlaceholderConverted()) . "<br>"; print "ERROR: " . $db->dbGetLastError(true) . "<br>";
print "<b>[$info]</b> " . Support::printAr($db->dbGetPlaceholderConverted()) . "<br>";
echo "<hr>"; echo "<hr>";
} }
@@ -188,21 +291,44 @@ SQL,
['string A-1'] ['string A-1']
)) ))
) { ) {
print "RES: " . Support::prAr($res) . "<br>"; print "<b>RES</b>: " . Support::prAr($res) . "<br>";
} }
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>";
print "CursorExt: " . Support::prAr($db->dbGetCursorExt(<<<SQL print "CursorExt: " . Support::prAr($db->dbGetCursorExt(<<<SQL
SELECT test, string_a, number_a SELECT test, string_a, number_a
FROM test_foo FROM test_foo
WHERE string_a = ? WHERE string_a = ?
SQL, ['string A-1'])); SQL, ['string A-1']));
echo "<hr>";
// ERROR BELOW: missing params
$res = $db->dbReturnRowParams(<<<SQL $res = $db->dbReturnRowParams(<<<SQL
SELECT test, string_a, number_a SELECT test, string_a, number_a
FROM test_foo FROM test_foo
WHERE string_a = $1 WHERE string_a = $1
SQL, []); SQL, []);
print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "<br>"; print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "<br>";
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
echo "<hr>";
// ERROR BELOW: LIKE cannot have placeholder
echo "dbReturn read LIKE: <br>";
while (
is_array($res = $db->dbReturnParams(
<<<SQL
SELECT test, string_a, number_a
FROM test_foo
WHERE string_a LIKE ?
SQL,
['%A-1%']
))
) {
print "RES: " . Support::prAr($res) . "<br>";
}
print "PL: " . Support::PrAr($db->dbGetPlaceholderConverted()) . "<br>";
print "ERROR: " . $db->dbGetLastError(true) . "<br>";
print "</body></html>"; print "</body></html>";
$db->log->debug('DEBUGEND', '==================================== [END]'); $db->log->debug('DEBUGEND', '==================================== [END]');

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -7,7 +7,7 @@
declare(strict_types=1); declare(strict_types=1);
// turn on all error reporting // turn on all error reporting
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -57,6 +57,43 @@ if (($dbh = $db->dbGetDbh()) instanceof \PgSql\Connection) {
print "<b>TRUNCATE test_foo</b><br>"; print "<b>TRUNCATE test_foo</b><br>";
$db->dbExec("TRUNCATE test_foo"); $db->dbExec("TRUNCATE test_foo");
/*
BELOW IS THE FULL TABLE WITH ALL PostgreSQL Types
=> \d test_foo
Table "public.test_foo"
Column | Type | Nullable | Default
------------------+-----------------------------+----------+-----------------------------------------------
test | character varying | |
some_bool | boolean | |
string_a | character varying | |
number_a | integer | |
numeric_a | numeric | |
some_internval | interval | |
test_foo_id | integer | not null | generated always as identity
json_string | jsonb | |
some_timestamp | timestamp without time zone | |
some_binary | bytea | |
null_var | character varying | |
smallint_a | smallint | |
number_real | real | |
number_double | double precision | |
number_serial | integer | not null | nextval('test_foo_number_serial_seq'::regclass)
array_char_1 | character varying[] | |
array_char_2 | character varying[] | |
array_int_1 | integer[] | |
array_int_2 | integer[] | |
composite_item | inventory_item | |
array_composite | inventory_item[] | |
numeric_3 | numeric(3,0) | |
identity_always | bigint | not null | generated always as identity
identitiy_default | bigint | not null | generated by default as identity
uuid_var | uuid | | gen_random_uuid()
some_date | date | |
some_time | time without time zone | |
bigint_a | bigint | |
default_uuid | uuid | | gen_random_uuid()
*/
/* $q = <<<SQL /* $q = <<<SQL
INSERT INTO test_foo (test, array_composite) VALUES ('C', '{"(a,1,1.5)","(b,2,2.5)"}') INSERT INTO test_foo (test, array_composite) VALUES ('C', '{"(a,1,1.5)","(b,2,2.5)"}')
SQL; SQL;
@@ -90,7 +127,7 @@ $query_params = [
$query_insert = <<<SQL $query_insert = <<<SQL
INSERT INTO test_foo ( INSERT INTO test_foo (
test, some_bool, string_a, number_a, number_a_numeric, smallint_a, test, some_bool, string_a, number_a, numeric_a, smallint_a,
some_time, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1, array_char_1, array_int_1,
array_composite, array_composite,
@@ -106,7 +143,7 @@ INSERT INTO test_foo (
) )
RETURNING RETURNING
test_foo_id, test_foo_id,
test, some_bool, string_a, number_a, number_a_numeric, smallint_a, test, some_bool, string_a, number_a, numeric_a, smallint_a,
some_time, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_int_1, array_char_1, array_int_1,
array_composite, array_composite,
@@ -127,8 +164,8 @@ echo "<hr>";
$query_select = <<<SQL $query_select = <<<SQL
SELECT SELECT
test_foo_id, test_foo_id,
test, some_bool, string_a, number_a, number_a_numeric, smallint_a, test, some_bool, string_a, number_a, numeric_a, smallint_a,
number_real, number_double, number_numeric_3, number_serial, number_real, number_double, numeric_3, number_serial,
some_time, some_timestamp, json_string, null_var, some_time, some_timestamp, json_string, null_var,
array_char_1, array_char_2, array_int_1, array_int_2, array_composite, array_char_1, array_char_2, array_int_1, array_int_2, array_composite,
composite_item, (composite_item).*, composite_item, (composite_item).*,

View File

@@ -12,7 +12,7 @@ $PRINT_ALL = false;
$ECHO_ALL = true; $ECHO_ALL = true;
$DB_DEBUG = true; $DB_DEBUG = true;
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -68,6 +68,14 @@ function test2(): array
return DebugSupport::getCallerMethodList(1); return DebugSupport::getCallerMethodList(1);
} }
// date stueff
print "printTime(-1): " . DebugSupport::printTime() . "<br>";
print "printTime(2): " . DebugSupport::printTime(2) . "<br>";
print "printTime(3): " . DebugSupport::printTime(3) . "<br>";
print "printTime(5): " . DebugSupport::printTime(5) . "<br>";
print "printIsoTime(): " . DebugSupport::printIsoTime() . "<br>";
print "printIsoTime(false): " . DebugSupport::printIsoTime(false) . "<br>";
print "S::GETCALLERMETHOD: " . DebugSupport::getCallerMethod(0) . "<br>"; print "S::GETCALLERMETHOD: " . DebugSupport::getCallerMethod(0) . "<br>";
print "S::GETCALLERMETHOD: " . test() . "<br>"; print "S::GETCALLERMETHOD: " . test() . "<br>";
print "S::GETCALLERMETHODLIST: <pre>" . print_r(test2(), true) . "</pre><br>"; print "S::GETCALLERMETHODLIST: <pre>" . print_r(test2(), true) . "</pre><br>";
@@ -146,7 +154,7 @@ print "LOG LEVEL: " . DebugSupport::printAr(\CoreLibs\Convert\SetVarType::setAr
$new_log->getLogLevel('debug', 'on') $new_log->getLogLevel('debug', 'on')
)) . "<br>"; )) . "<br>";
echo "<b>CLASS DEBUG CALL</b><br>"; echo "<b>CLASS DEBUG CALL LEGACY</b><br>";
// @codingStandardsIgnoreLine // @codingStandardsIgnoreLine
class TestL class TestL

View File

@@ -0,0 +1,110 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', false);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-phpv';
ob_end_flush();
$log = new CoreLibs\Logging\Logging([
'log_folder' => 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 "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
// fputcsv
print "<h3>\CoreLibs\DeprecatedHelper\Deprecated84::fputcsv()</h3>";
$test_csv = BASE . TMP . 'DeprecatedHelper.test.csv';
print "File: $test_csv<br>";
$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: <pre>" . print_r($entry, true) . "</pre>";
}
fclose($fp);
$out = \CoreLibs\DeprecatedHelper\Deprecated84::str_getcsv("A,B,C");
print "str_getcsv: <pre>" . print_r($out, true) . "</pre>";
/**
* 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<int,string|null> 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 ($string === false) {
return $lines;
}
}
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 "</body></html>";
// __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -18,6 +18,7 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-encryption'; $LOG_FILE_ID = 'classTest-encryption';
ob_end_flush(); ob_end_flush();
use CoreLibs\Security\AsymmetricAnonymousEncryption;
use CoreLibs\Security\SymmetricEncryption; use CoreLibs\Security\SymmetricEncryption;
use CoreLibs\Security\CreateKey; use CoreLibs\Security\CreateKey;
@@ -36,6 +37,8 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>'; print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "<h2>Symmetric Encryption</h2>";
$key = CreateKey::generateRandomKey(); $key = CreateKey::generateRandomKey();
print "Secret Key: " . $key . "<br>"; print "Secret Key: " . $key . "<br>";
@@ -105,6 +108,49 @@ try {
// $encrypted = $se->encrypt($string); // $encrypted = $se->encrypt($string);
// $decrypted = $se->decrypt($encrypted); // $decrypted = $se->decrypt($encrypted);
echo "<hr>";
print "<h2>Asymmetric Encryption</h2>";
$key_pair = CreateKey::createKeyPair();
$public_key = CreateKey::getPublicKey($key_pair);
$string = "I am some asymmetric secret";
print "Message: " . $string . "<br>";
$encrypted = sodium_crypto_box_seal($string, CreateKey::hex2bin($public_key));
$message = sodium_bin2base64($encrypted, SODIUM_BASE64_VARIANT_ORIGINAL);
print "Encrypted PL: " . $message . "<br>";
$result = sodium_base642bin($message, SODIUM_BASE64_VARIANT_ORIGINAL);
$decrypted = sodium_crypto_box_seal_open($result, CreateKey::hex2bin($key_pair));
print "Decrypted PL: " . $decrypted . "<br>";
$encrypted = AsymmetricAnonymousEncryption::encryptKey($string, $public_key);
print "Encrypted ST: " . $encrypted . "<br>";
$decrypted = AsymmetricAnonymousEncryption::decryptKey($encrypted, $key_pair);
print "Decrypted ST: " . $decrypted . "<br>";
$aa_crypt = new AsymmetricAnonymousEncryption($key_pair, $public_key);
$encrypted = $aa_crypt->encrypt($string);
print "Encrypted: " . $encrypted . "<br>";
$decrypted = $aa_crypt->decrypt($encrypted);
print "Decrypted: " . $decrypted . "<br>";
print "Base64 encode: " . base64_encode('Some text here') . "<Br>";
/// this has to fail
$crypt = new AsymmetricAnonymousEncryption();
$crypt->setPublicKey(CreateKey::getPublicKey(CreateKey::createKeyPair()));
print "Public Key: " . $crypt->getPublicKey() . "<br>";
try {
$crypt->setPublicKey(CreateKey::createKeyPair());
} catch (RangeException $e) {
print "Invalid range: <pre>$e</pre>";
}
try {
$crypt->setKeyPair(CreateKey::getPublicKey(CreateKey::createKeyPair()));
} catch (RangeException $e) {
print "Invalid range: <pre>$e</pre>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -40,11 +40,15 @@ print "Log ERROR: " . $log->prAr($em->getFlagLogError()) . "<br>";
print "FN: " . ml::fromName('Affe')->name . "<br>"; print "FN: " . ml::fromName('Affe')->name . "<br>";
print "NU: " . ml::fromValue(100)->name . "<br>"; print "NU: " . ml::fromValue(100)->name . "<br>";
print "NU: " . ml::fromValue(1000)->name . "<br>"; print "NU: " . ml::fromValue(1000)->name . "<br>";
print "OK.: " . ml::ok->name . "<br>";
print "OK^: " . ml::fromName('OK')->name . "<br>";
$em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug'); $em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug');
$em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug', 'target-id', 'other-style'); $em->setErrorMsg('123', 'error', 'msg this is bad, auto logged if debug', 'target-id', 'other-style');
$em->setErrorMsg('123', 'error', 'msg this is bad, logged always', log_error:true); $em->setErrorMsg('123', 'error', 'msg this is bad, logged always', log_error:true);
$em->setErrorMsg('123', 'error', 'msg this is bad, never logged', log_error:false); $em->setErrorMsg('123', 'error', 'msg this is bad, never logged', log_error:false);
$em->setErrorMsg('500', 'warning', 'This is perhaps not super good, logged_always', log_warning:true);
$em->setErrorMsg('500', 'warning', 'This is perhaps not super good, logged_never', log_warning:false);
$em->setErrorMsg('1000', 'info', 'This is good'); $em->setErrorMsg('1000', 'info', 'This is good');
$em->setErrorMsg('9999', 'abort', 'BAD: This is critical (abort)'); $em->setErrorMsg('9999', 'abort', 'BAD: This is critical (abort)');
$em->setErrorMsg('10-1000', 'wrong', 'Wrong level: This is emergency'); $em->setErrorMsg('10-1000', 'wrong', 'Wrong level: This is emergency');
@@ -54,11 +58,21 @@ $em->setErrorMsg('100-2', 'error', 'Input wring', jump_target:['target' => 'foo-
$em->setMessage('error', 'I have no id set', jump_target:['target' => 'bar-123', 'info' => 'Jump Bar']); $em->setMessage('error', 'I have no id set', jump_target:['target' => 'bar-123', 'info' => 'Jump Bar']);
$em->setMessage('error', 'Jump empty', jump_target:['target' => 'bar-empty']); $em->setMessage('error', 'Jump empty', jump_target:['target' => 'bar-empty']);
function inLine(\CoreLibs\Logging\ErrorMessage $em): void
{
$em->log->error('Direct log before from ', context:['function' => __FUNCTION__]);
$em->setMessage('error', 'Inline call', context:['test' => 'inLine Function']);
$em->log->error('Direct log from ', context:['function' => __FUNCTION__]);
}
inLine($em);
print "ErrorsLast: <pre>" . $log->prAr($em->getLastErrorMsg()) . "</pre>"; print "ErrorsLast: <pre>" . $log->prAr($em->getLastErrorMsg()) . "</pre>";
print "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>"; print "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>";
print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>"; print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>";
print "JumpTargets: <pre>" . $log->prAr($em->getJumpTarget()) . "</pre>"; print "JumpTargets: <pre>" . $log->prAr($em->getJumpTarget()) . "</pre>";
print "IS info > ok: " . ml::fromName('info')->isHigherThan(ml::ok) . "<br>";
print "</body></html>"; print "</body></html>";
$log->debug('[END]', '==========================================>'); $log->debug('[END]', '==========================================>');

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -19,6 +19,7 @@ $LOG_FILE_ID = 'classTest-hash';
ob_end_flush(); ob_end_flush();
use CoreLibs\Create\Hash; use CoreLibs\Create\Hash;
use CoreLibs\Security\CreateKey;
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
@@ -38,28 +39,66 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$to_crc = 'Some text block'; $to_crc = 'Some text block';
// static // static
print "S::__CRC32B: $to_crc: " . $hash_class::__crc32b($to_crc) . "<br>"; print "S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>";
print "S::__SHA1SHORT(off): $to_crc: " . $hash_class::__sha1short($to_crc) . "<br>"; // print "S::__SHA1SHORT(off): $to_crc: " . Hash::__sha1short($to_crc) . "<br>";
print "S::__SHA1SHORT(on): $to_crc: " . $hash_class::__sha1short($to_crc, true) . "<br>"; print "S::hashShort(__sha1Short replace): $to_crc: " . Hash::hashShort($to_crc) . "<br>";
print "S::__hash(d): " . $to_crc . "/" // print "S::__SHA1SHORT(on): $to_crc: " . Hash::__sha1short($to_crc, true) . "<br>";
. Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "<br>"; print "S::sha1Short(__sha1Short replace): $to_crc: " . Hash::sha1Short($to_crc) . "<br>";
foreach (['adler32', 'fnv132', 'fnv1a32', 'joaat', 'sha512'] as $__hash_c) { // print "S::__hash(d): " . $to_crc . "/"
print "S::__hash($__hash_c): $to_crc: " . $hash_class::__hash($to_crc, $__hash_c) . "<br>"; // . Hash::STANDARD_HASH_SHORT . ": " . $hash_class::__hash($to_crc) . "<br>";
$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) . "<br>";
}
} }
// static use // static use
print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>"; print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "<br>";
echo "<hr>"; echo "<hr>";
$text = 'Some String Text'; $text = 'Some String Text';
// $text = 'any string';
$type = 'crc32b'; $type = 'crc32b';
print "Hash: " . $type . ": " . hash($type, $text) . "<br>"; print "Hash: " . $type . ": " . hash($type, $text) . "<br>";
print "Class: " . $type . ": " . Hash::__hash($text, $type) . "<br>"; // print "Class (old): " . $type . ": " . Hash::__hash($text, $type) . "<br>";
print "Class (new): " . $type . ": " . Hash::hash($text, $type) . "<br>";
echo "<hr>"; echo "<hr>";
print "<br>CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "<br>"; print "CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "<br>";
print "<br>CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "<br>"; print "CURRENT STANDARD_HASH_LONG: " . Hash::STANDARD_HASH_LONG . "<br>";
print "HASH SHORT: " . $to_crc . ": " . Hash::__hash($to_crc) . "<br>"; print "CURRENT STANDARD_HASH: " . Hash::STANDARD_HASH . "<br>";
print "HASH LONG: " . $to_crc . ": " . Hash::__hashLong($to_crc) . "<br>"; print "HASH SHORT: " . $to_crc . ": " . Hash::hashShort($to_crc) . "<br>";
print "HASH LONG: " . $to_crc . ": " . Hash::hashLong($to_crc) . "<br>";
print "HASH DEFAULT: " . $to_crc . ": " . Hash::hashStd($to_crc) . "<br>";
echo "<hr>";
$key = CreateKey::generateRandomKey();
$key = "FIX KEY";
print "Secret Key: " . $key . "<br>";
print "HASHMAC DEFAULT (fix): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "<br>";
$key = CreateKey::generateRandomKey();
print "Secret Key: " . $key . "<br>";
print "HASHMAC DEFAULT (random): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "<br>";
echo "<hr>";
$hash_types = ['crc32b', 'sha256', 'invalid'];
foreach ($hash_types as $hash_type) {
echo "<b>Checking $hash_type:</b><br>";
if (Hash::isValidHashType($hash_type)) {
echo "hash type: $hash_type is valid<br>";
} else {
echo "hash type: $hash_type is INVALID<br>";
}
if (Hash::isValidHashHmacType($hash_type)) {
echo "hash hmac type: $hash_type is valid<br>";
} else {
echo "hash hmac type: $hash_type is INVALID<br>";
}
}
// print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>"; // print "UNIQU ID SHORT : " . Hash::__uniqId() . "<br>";
// print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>"; // print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "<br>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -42,6 +42,7 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$string = "Something < = > Other <br> Next line and Quotes '\""; $string = "Something < = > Other <br> Next line and Quotes '\"";
echo "String: <pre>$string</pre><br>"; echo "String: <pre>$string</pre><br>";
$log->debug('HTMLENT', Html::htmlent($string));
print "HTMLENT: " . Html::htmlent($string) . ": " . $_html->htmlent($string) . " (" . htmlentities($string) . ")<br>"; print "HTMLENT: " . Html::htmlent($string) . ": " . $_html->htmlent($string) . " (" . htmlentities($string) . ")<br>";
print "REMOVELB: " . Html::htmlent($string) . ": " . $_html->removeLB($string) . "<br>"; print "REMOVELB: " . Html::htmlent($string) . ": " . $_html->removeLB($string) . "<br>";
$date_str = [2021, 5, 1, 11, 10]; $date_str = [2021, 5, 1, 11, 10];
@@ -68,8 +69,10 @@ $checked_list = [
['foo', ['bar']], ['foo', ['bar']],
]; ];
foreach ($checked_list as $check) { foreach ($checked_list as $check) {
print "CHECKED(0): $check[0]: " . Html::checked($check[1], $check[0]) . "<br>"; print "CHECKED(0): " . $check[0] . " -> " . print_r($check[1], true) . ": "
print "CHECKED(1): $check[0]: " . Html::checked($check[1], $check[0], Html::CHECKED) . "<br>"; . Html::checked($check[1], $check[0]) . "<br>";
print "CHECKED(1): " . $check[0] . " -> " . print_r($check[1], true) . ": "
. Html::checked($check[1], $check[0], Html::CHECKED) . "<br>";
} }
// magic link creation test // magic link creation test

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -74,8 +74,8 @@ print "EL_O: <pre>" . print_r($el_o, true) . "</pre>";
echo "<hr>"; echo "<hr>";
print "buildHtml(): <pre>" . htmlentities($el_o->buildHtml()) . "</pre>"; print "buildHtml(): <pre>" . htmlentities($el_o->buildHtml()) . "</pre>";
echo "<hr>"; /* echo "<hr>";
print "phfo(\$el_o): <pre>" . htmlentities($el_o::printHtmlFromObject($el_o, true)) . "</pre>"; print "phfo(\$el_o): <pre>" . htmlentities($el_o::printHtmlFromObject($el_o, true)) . "</pre>"; */
echo "<hr>"; echo "<hr>";
print "phfa(\$el_list): <pre>" . htmlentities($el_o::buildHtmlFromList($el_o_list, true)) . "</pre>"; print "phfa(\$el_list): <pre>" . htmlentities($el_o::buildHtmlFromList($el_o_list, true)) . "</pre>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -67,6 +67,8 @@ print "J/S::E-JSON ERROR: " . $json_class::jsonGetLastError() . ": " . $json_cla
$array = ['foo' => 'bar']; $array = ['foo' => 'bar'];
$output = Json::jsonConvertArrayTo($array); $output = Json::jsonConvertArrayTo($array);
print "S::JSON: " . DgS::printAr($array) . " => " . $output . "<br>"; print "S::JSON: " . DgS::printAr($array) . " => " . $output . "<br>";
$array = ['foo' => 'bar', 'sub' => ['other' => 'this', 'foo' => 'bar', 'set' => [12, 34, true]]];
print "Pretty: <pre>" . Json::jsonPrettyPrint($array) . "</pre><br>";
print "</body></html>"; print "</body></html>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -16,6 +16,8 @@ define('USE_DATABASE', false);
require 'config.php'; require 'config.php';
// define log file id // define log file id
$LOG_FILE_ID = 'classTest-lang'; $LOG_FILE_ID = 'classTest-lang';
$SET_SESSION_NAME = EDIT_SESSION_NAME;
$session = new CoreLibs\Create\Session($SET_SESSION_NAME);
ob_end_flush(); ob_end_flush();
$PAGE_NAME = 'TEST CLASS: LANG'; $PAGE_NAME = 'TEST CLASS: LANG';
@@ -32,22 +34,21 @@ use CoreLibs\Debug\Support;
echo "<br><b>LIST LOCALES</b><br>"; echo "<br><b>LIST LOCALES</b><br>";
$locale = 'en_US.UTF-8'; $locale = 'en_US.UTF-8';
$locales = L10n::listLocales($locale); $locales = Language\L10n::listLocales($locale);
print "[" . $locale . "] LOCALES: " . Support::printAr($locales) . "<br>"; print "[" . $locale . "] LOCALES: " . Support::printAr($locales) . "<br>";
$locale = 'en.UTF-8'; $locale = 'en.UTF-8';
$locales = L10n::listLocales($locale); $locales = Language\L10n::listLocales($locale);
print "[" . $locale . "] LOCALES: " . Support::printAr($locales) . "<br>"; print "[" . $locale . "] LOCALES: " . Support::printAr($locales) . "<br>";
echo "<br><b>PARSE LOCAL</b><br>"; echo "<br><b>PARSE LOCAL</b><br>";
$locale = 'en_US.UTF-8'; $locale = 'en_US.UTF-8';
$locale_info = L10n::parseLocale($locale); $locale_info = Language\L10n::parseLocale($locale);
print "[" . $locale . "] INFO: " . Support::printAr($locale_info) . "<br>"; print "[" . $locale . "] INFO: " . Support::printAr($locale_info) . "<br>";
$locale = 'en.UTF-8'; $locale = 'en.UTF-8';
$locale_info = L10n::parseLocale($locale); $locale_info = Language\L10n::parseLocale($locale);
print "[" . $locale . "] INFO: " . Support::printAr($locale_info) . "<br>"; print "[" . $locale . "] INFO: " . Support::printAr($locale_info) . "<br>";
echo "<br><b>AUTO DETECT</b><br>"; /* echo "<br><b>AUTO DETECT</b><br>";
// DEPRECATED // DEPRECATED
// $get_locale = Language\GetLocale::setLocale(); // $get_locale = Language\GetLocale::setLocale();
// print "[AUTO, DEPRECATED]: " . Support::printAr($get_locale) . "<br>"; // print "[AUTO, DEPRECATED]: " . Support::printAr($get_locale) . "<br>";
@@ -70,10 +71,12 @@ print "[OVERRIDE]: " . Support::printAr($get_locale) . "<br>";
// DEFAULT_DOMAIN // DEFAULT_DOMAIN
// DEFAULT_CHARSET (should be set from DEFAULT_LOCALE) // DEFAULT_CHARSET (should be set from DEFAULT_LOCALE)
// LOCALE_PATH // LOCALE_PATH
$_SESSION['DEFAULT_LOCALE'] = 'ja_JP.UTF-8'; $session->setMany([
$_SESSION['DEFAULT_CHARSET'] = 'UTF-8'; 'DEFAULT_LOCALE' => 'ja_JP.UTF-8',
$_SESSION['DEFAULT_DOMAIN'] = 'admin'; 'DEFAULT_CHARSET' => 'UTF-8',
$_SESSION['LOCALE_PATH'] = BASE . INCLUDES . LOCALE; 'DEFAULT_DOMAIN' => 'admin',
'LOCALE_PATH' => BASE . INCLUDES . LOCALE,
]);
$get_locale = Language\GetLocale::setLocaleFromSession( $get_locale = Language\GetLocale::setLocaleFromSession(
SITE_LOCALE, SITE_LOCALE,
SITE_DOMAIN, SITE_DOMAIN,
@@ -86,10 +89,12 @@ print "[SESSION SET]: " . Support::printAr($get_locale) . "<br>";
// DEFAULT_DOMAIN // DEFAULT_DOMAIN
// DEFAULT_CHARSET (should be set from DEFAULT_LOCALE) // DEFAULT_CHARSET (should be set from DEFAULT_LOCALE)
// LOCALE_PATH // LOCALE_PATH
$_SESSION['DEFAULT_LOCALE'] = '00000#####'; $session->setMany([
$_SESSION['DEFAULT_CHARSET'] = ''; 'DEFAULT_LOCALE' => '00000#####',
$_SESSION['DEFAULT_DOMAIN'] = 'admin'; 'DEFAULT_CHARSET' => '',
$_SESSION['LOCALE_PATH'] = BASE . INCLUDES . LOCALE; 'DEFAULT_DOMAIN' => 'admin',
'LOCALE_PATH' => BASE . INCLUDES . LOCALE,
]);
$get_locale = Language\GetLocale::setLocaleFromSession( $get_locale = Language\GetLocale::setLocaleFromSession(
SITE_LOCALE, SITE_LOCALE,
SITE_DOMAIN, SITE_DOMAIN,
@@ -97,6 +102,7 @@ $get_locale = Language\GetLocale::setLocaleFromSession(
BASE . INCLUDES . LOCALE BASE . INCLUDES . LOCALE
); );
print "[SESSION SET INVALID]: " . Support::printAr($get_locale) . "<br>"; print "[SESSION SET INVALID]: " . Support::printAr($get_locale) . "<br>";
*/
// try to load non existing // try to load non existing
echo "<br><b>NEW TYPE</b><br>"; echo "<br><b>NEW TYPE</b><br>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -82,6 +82,7 @@ $log->error('Cannot process data', ['error' => 'log']);
$log->critical('Critical message', ['critical' => 'log']); $log->critical('Critical message', ['critical' => 'log']);
$log->alert('Alert message', ['Alert' => 'log']); $log->alert('Alert message', ['Alert' => 'log']);
$log->emergency('Emergency message', ['Emergency' => 'log']); $log->emergency('Emergency message', ['Emergency' => 'log']);
error_log('TRIGGER ERROR LOG MANUAL: Emergency');
print "Log File: " . $log->getLogFile() . "<br>"; print "Log File: " . $log->getLogFile() . "<br>";
$log->setLogFlag(Flag::per_run); $log->setLogFlag(Flag::per_run);
@@ -120,6 +121,12 @@ Class TestP
public function test(): void public function test(): void
{ {
$this->log->info('TestL::test call'); $this->log->info('TestL::test call');
$this->subCall();
}
public function subCall(): void
{
$this->log->info('TestL::sub_call call');
} }
} }

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -17,14 +17,21 @@ require 'config.php';
// define log file id // define log file id
$LOG_FILE_ID = 'classTest-login'; $LOG_FILE_ID = 'classTest-login';
$SET_SESSION_NAME = EDIT_SESSION_NAME; $SET_SESSION_NAME = EDIT_SESSION_NAME;
use CoreLibs\Debug\Support;
// init login & backend class // init login & backend class
$session = new CoreLibs\Create\Session($SET_SESSION_NAME); $session = new CoreLibs\Create\Session($SET_SESSION_NAME, [
'regenerate' => 'interval',
'regenerate_interval' => 10, // every 10 seconds
]);
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true, 'log_per_date' => true,
]); ]);
$db = new CoreLibs\DB\IO(DB_CONFIG, $log); $db = new CoreLibs\DB\IO(DB_CONFIG, $log);
$log->setLogFileId('classTest-login-override');
$login = new CoreLibs\ACL\Login( $login = new CoreLibs\ACL\Login(
$db, $db,
$log, $log,
@@ -39,23 +46,120 @@ $login = new CoreLibs\ACL\Login(
'locale_path' => BASE . INCLUDES . LOCALE, 'locale_path' => BASE . INCLUDES . LOCALE,
] ]
); );
$log->setLogFileId($LOG_FILE_ID);
ob_end_flush(); ob_end_flush();
$login->loginMainCall(); $login->loginMainCall();
$PAGE_NAME = 'TEST CLASS: LOGIN'; $PAGE_NAME = 'TEST CLASS: LOGIN';
print "<!DOCTYPE html>"; print str_replace(
print "<html><head><title>" . $PAGE_NAME . "</title></head>"; '{PAGE_NAME}',
print "<body>"; $PAGE_NAME,
print '<div><a href="class_test.php">Class Test Master</a></div>'; <<<HTML
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; <!DOCTYPE html>
<html><head>
<title>{PAGE_NAME}</title>
</head>
<body>
<div><a href="class_test.php">Class Test Master</a></div>
<div><h1>{PAGE_NAME}</h1></div>
HTML
);
// button logout
print <<<HTML
<script language="JavaScript">
function loginLogout()
{
const form = document.createElement('form');
form.method = 'post';
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = 'login_logout';
hiddenField.value = 'Logout';
form.appendChild(hiddenField);
document.body.appendChild(form);
form.submit();
}
</script>
<div style="margin: 20px 0;">
<button onclick="loginLogout();" type="button">Logout</button>
</div>
HTML;
// string logout
print <<<HTML
<div style="margin: 20px 0;">
<form method="post" name="loginlogout">
<a href="javascript:document.loginlogout.login_logout.value=Logout;document.loginlogout.submit();">Logout</a>
<input type="hidden" name="login_logout" value="">
</form>
</div>
HTML;
echo "SESSION ID: " . $session->getSessionIdCall() . "<br>";
echo "CHECK PERMISSION: " . ($login->loginCheckPermissions() ? 'OK' : 'BAD') . "<br>"; echo "CHECK PERMISSION: " . ($login->loginCheckPermissions() ? 'OK' : 'BAD') . "<br>";
echo "IS ADMIN: " . ($login->loginIsAdmin() ? 'OK' : 'BAD') . "<br>"; echo "IS ADMIN: " . ($login->loginIsAdmin() ? 'OK' : 'BAD') . "<br>";
echo "MIN ACCESS BASE: " . ($login->loginCheckAccessBase('admin') ? 'OK' : 'BAD') . "<br>"; echo "MIN ACCESS BASE: " . ($login->loginCheckAccessBase('admin') ? 'OK' : 'BAD') . "<br>";
echo "MIN ACCESS PAGE: " . ($login->loginCheckAccessPage('admin') ? 'OK' : 'BAD') . "<br>"; echo "MIN ACCESS PAGE: " . ($login->loginCheckAccessPage('admin') ? 'OK' : 'BAD') . "<br>";
echo "ACL: " . \CoreLibs\Debug\Support::printAr($login->loginGetAcl()) . "<br>"; echo "ACL: " . Support::printAr($login->loginGetAcl()) . "<br>";
echo "ACL (MIN): " . \CoreLibs\Debug\Support::printAr($login->loginGetAcl()['min'] ?? []) . "<br>"; echo "ACL (MIN): " . Support::printAr($login->loginGetAcl()['min'] ?? []) . "<br>";
echo "LOCALE: " . \CoreLibs\Debug\Support::printAr($login->loginGetLocale()) . "<br>"; echo "LOCALE: " . Support::printAr($login->loginGetLocale()) . "<br>";
echo "ECUID: " . $login->loginGetEuCuid() . "<br>";
echo "ECUUID: " . $login->loginGetEuCuuid() . "<br>";
echo "<hr>";
// set + check edit access id
$edit_access_cuid = 'buRW8Gu2Lkkf';
if (isset($login->loginGetAcl()['unit'])) {
print "EDIT ACCESS CUID: " . $edit_access_cuid . "<br>";
print "ACL UNIT: " . print_r(array_keys($login->loginGetAcl()['unit']), true) . "<br>";
print "ACCESS CHECK: " . Support::prBl($login->loginCheckEditAccessCuid($edit_access_cuid)) . "<br>";
if ($login->loginCheckEditAccessCuid($edit_access_cuid)) {
print "Set new:" . $edit_access_cuid . "<br>";
} else {
print "Load default unit id: " . $login->loginGetAcl()['unit_cuid'] . "<br>";
}
} else {
print "Something went wrong with the login<br>";
}
// echo "<hr>";
// IP check: 'REMOTE_ADDR', 'HTTP_X_FORWARDED_FOR', 'CLIENT_IP' in _SERVER
// Agent check: 'HTTP_USER_AGENT'
print "<hr>";
print "PAGE lookup:<br>";
$file_name = 'test_edit_base.php';
print "Access to '$file_name': " . $log->prAr($login->loginPageAccessAllowed($file_name)) . "<br>";
$file_name = 'i_do_not_exists.php';
print "Access to '$file_name': " . $log->prAr($login->loginPageAccessAllowed($file_name)) . "<br>";
echo "<hr>";
print "SESSION: " . Support::printAr($_SESSION) . "<br>";
$login->writeLog(
'TEST LOG',
[
'test' => 'TEST A'
],
error:'No Error',
write_type:'JSON'
);
echo "<hr>";
print "<h3>Legacy Lookups</h3>";
$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 . "<br>";
print "EA CUID: " . $log->prAr($edit_access_cuid) . "<br>";
print "REV EA CUID: " . $log->prAr($edit_access_id_rev) . "<br>";
$log->info('This is a test');
print "</body></html>"; print "</body></html>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -23,7 +23,6 @@ $log = new CoreLibs\Logging\Logging([
'log_file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true, 'log_per_date' => true,
]); ]);
$_math = new CoreLibs\Convert\Math();
$math_class = 'CoreLibs\Convert\Math'; $math_class = 'CoreLibs\Convert\Math';
// define a list of from to color sets for conversion test // define a list of from to color sets for conversion test
@@ -35,13 +34,9 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>'; print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "FCEIL: " . $_math->fceil(5.1234567890, 5) . "<br>";
print "FLOORP: " . $_math->floorp(5123456, -3) . "<br>";
print "FLOORP: " . $_math->floorp(5123456, -10) . "<br>";
print "INITNUMERIC: " . $_math->initNumeric('123') . "<br>";
print "S-FCEIL: " . $math_class::fceil(5.1234567890, 5) . "<br>"; print "S-FCEIL: " . $math_class::fceil(5.1234567890, 5) . "<br>";
print "S-FLOORP: " . $math_class::floorp(5123456, -3) . "<br>"; print "S-FLOORP: " . $math_class::floorp(5123456, -3) . "<br>";
print "S-FLOORP: " . $math_class::floorp(5123456, -10) . "<br>";
print "S-INITNUMERIC: " . $math_class::initNumeric(123) . "<br>"; print "S-INITNUMERIC: " . $math_class::initNumeric(123) . "<br>";
print "S-INITNUMERIC: " . $math_class::initNumeric(123.456) . "<br>"; print "S-INITNUMERIC: " . $math_class::initNumeric(123.456) . "<br>";
print "S-INITNUMERIC: " . $math_class::initNumeric('123') . "<br>"; print "S-INITNUMERIC: " . $math_class::initNumeric('123') . "<br>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -29,15 +29,17 @@ $table_arrays = [];
$table_arrays[\CoreLibs\Get\System::getPageName(1)] = [ $table_arrays[\CoreLibs\Get\System::getPageName(1)] = [
// form fields mtaching up with db fields // form fields mtaching up with db fields
'table_array' => [ 'table_array' => [
'foo',
'bar'
], ],
// laod query // laod query
'load_query' => '', 'load_query' => 'SELECT uuid_nr, foo, bar FROM test',
// database table to load from // database table to load from
'table_name' => '', 'table_name' => 'test',
// for load dro pdown, format output // for load dro pdown, format output
'show_fields' => [ 'show_fields' => [
[ [
'name' => 'name' 'name' => 'foo'
], ],
[ [
'name' => 'enabled', 'name' => 'enabled',

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -37,6 +37,8 @@ print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>'; print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "PHP Version: " . PHP_VERSION . "<br>";
$password = 'something1234'; $password = 'something1234';
$enc_password = $_password->passwordSet($password); $enc_password = $_password->passwordSet($password);
print "PASSWORD: $password: " . $enc_password . "<br>"; print "PASSWORD: $password: " . $enc_password . "<br>";
@@ -51,6 +53,20 @@ print "PASSWORD REHASH: " . (string)$password_class::passwordRehashCheck($enc_pa
// direct static // direct static
print "S::PASSWORD VERFIY: " . (string)PwdChk::passwordVerify($password, $enc_password) . "<br>"; print "S::PASSWORD VERFIY: " . (string)PwdChk::passwordVerify($password, $enc_password) . "<br>";
if (PHP_VERSION_ID < 80400) {
$rehash_test = '$2y$10$EgWJ2WE73DWi.hIyFRCdpejLXTvHbmTK3LEOclO1tAvXAXUNuUS4W';
$rehash_test_throw = '$2y$12$EgWJ2WE73DWi.hIyFRCdpejLXTvHbmTK3LEOclO1tAvXAXUNuUS4W';
} else {
$rehash_test = '$2y$12$EgWJ2WE73DWi.hIyFRCdpejLXTvHbmTK3LEOclO1tAvXAXUNuUS4W';
$rehash_test_throw = '$2y$10$EgWJ2WE73DWi.hIyFRCdpejLXTvHbmTK3LEOclO1tAvXAXUNuUS4W';
}
if (PwdChk::passwordRehashCheck($rehash_test)) {
print "Bad password [BAD]<br>";
}
if (PwdChk::passwordRehashCheck($rehash_test_throw)) {
print "Bad password [OK]<br>";
}
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -62,17 +62,40 @@ $backend = new CoreLibs\Admin\Backend(
$backend->db->dbInfo(true); $backend->db->dbInfo(true);
ob_end_flush(); ob_end_flush();
print "<!DOCTYPE html>"; print <<<HTML
print "<html><head><title>TEST CLASS</title></head>"; <!DOCTYPE html>
print "<body>"; <html><head>
<title>TEST CLASS</title>
<script language="JavaScript">
function loginLogout()
{
const form = document.createElement('form');
form.method = 'post';
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = 'login_logout';
hiddenField.value = 'Logout';
form.appendChild(hiddenField);
document.body.appendChild(form);
form.submit();
}
</script>
</head>
<body>
<div style="margin: 20px 0;">
<button onclick="loginLogout();" type="button">Logout</button>
</div>
HTML;
// key: file name, value; name // key: file name, value; name
$test_files = [ $test_files = [
'class_test.db.php' => 'Class Test: DB', 'class_test.db.php' => 'Class Test: DB',
'class_test.db.types.php' => 'Class Test: DB column type convert', 'class_test.db.types.php' => 'Class Test: DB column type convert',
'class_test.db.query-placeholder.php' => 'Class Test: DB query placeholder convert', 'class_test.db.query-placeholder.php' => 'Class Test: DB placeholder queries',
'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn', 'class_test.db.dbReturn.php' => 'Class Test: DB dbReturn',
'class_test.db.single.php' => 'Class Test: DB single query tests', '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.convert.colors.php' => 'Class Test: CONVERT COLORS',
'class_test.check.colors.php' => 'Class Test: CHECK COLORS', 'class_test.check.colors.php' => 'Class Test: CHECK COLORS',
'class_test.mime.php' => 'Class Test: MIME', 'class_test.mime.php' => 'Class Test: MIME',
@@ -117,7 +140,9 @@ $test_files = [
'class_test.config.direct.php' => 'Class Test: CONFIG DIRECT', 'class_test.config.direct.php' => 'Class Test: CONFIG DIRECT',
'class_test.class-calls.php' => 'Class Test: CLASS CALLS', 'class_test.class-calls.php' => 'Class Test: CLASS CALLS',
'class_test.error_msg.php' => 'Class Test: ERROR MSG', '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', 'subfolder/class_test.config.direct.php' => 'Class Test: CONFIG DIRECT SUB',
'class_test.deprecated.helper.php' => 'Class Test: DEPRECATED HELPERS',
]; ];
asort($test_files); asort($test_files);
@@ -126,33 +151,20 @@ foreach ($test_files as $file => $name) {
print '<div><a href="' . $file . '">' . $name . '</a></div>'; print '<div><a href="' . $file . '">' . $name . '</a></div>';
} }
print "<br>";
print "ECUID: " . $session->get('LOGIN_EUCUID') . "<br>";
print "ECUUID: " . $session->get('LOGIN_EUCUUID') . "<br>";
print "<hr>"; print "<hr>";
print "L: " . Support::dumpVar($locale) . "<br>"; print "LOCALE: " . Support::dumpVar($locale) . "<br>";
// print all _ENV vars set // print all _ENV vars set
print "<div>READ _ENV ARRAY:</div>"; print "<div>READ _ENV ARRAY:</div>";
print Support::dumpVar(array_map('htmlentities', $_ENV)); print Support::dumpVar(array_map('htmlentities', $_ENV));
// set + check edit access id
$edit_access_id = 3;
if (is_object($login) && isset($login->loginGetAcl()['unit'])) {
print "ACL UNIT: " . print_r(array_keys($login->loginGetAcl()['unit']), true) . "<br>";
print "ACCESS CHECK: " . (string)$login->loginCheckEditAccess($edit_access_id) . "<br>";
if ($login->loginCheckEditAccess($edit_access_id)) {
$backend->edit_access_id = $edit_access_id;
} else {
$backend->edit_access_id = $login->loginGetAcl()['unit_id'];
}
} else {
print "Something went wrong with the login<br>";
}
// $backend->log->debug('SESSION', \CoreLibs\Debug\Support::dumpVar($_SESSION)); // $backend->log->debug('SESSION', \CoreLibs\Debug\Support::dumpVar($_SESSION));
print '<form method="post" name="loginlogout">'; print "<br>";
print '<a href="javascript:document.loginlogout.login_logout.value=\'Logou\';'
. 'document.loginlogout.submit();">Logout</a>';
print '<input type="hidden" name="login_logout" value="">';
print '</form>';
print "Log Level: " . $backend->log->getLoggingLevel()->getName() . "<br>"; print "Log Level: " . $backend->log->getLoggingLevel()->getName() . "<br>";
print "Log ID: " . $backend->log->getLogFileId() . "<br>"; print "Log ID: " . $backend->log->getLogFileId() . "<br>";
print "Log Date: " . $backend->log->getLogDate() . "<br>"; print "Log Date: " . $backend->log->getLogDate() . "<br>";
@@ -174,28 +186,7 @@ foreach (
$log->debug('SOME MARK', 'Some error output'); $log->debug('SOME MARK', 'Some error output');
// INTERNAL SET print "<br>";
print "EDIT ACCESS ID: " . $backend->edit_access_id . "<br>";
if (is_object($login)) {
// print "ACL: <br>".$backend->print_ar($login->loginGetAcl())."<br>";
$log->debug('ACL', "ACL: " . \CoreLibs\Debug\Support::dumpVar($login->loginGetAcl()));
// print "DEFAULT ACL: <br>".$backend->print_ar($login->default_acl_list)."<br>";
// print "DEFAULT ACL: <br>".$backend->print_ar($login->default_acl_list)."<br>";
// $result = array_flip(
// array_filter(
// array_flip($login->default_acl_list),
// function ($key) {
// if (is_numeric($key)) {
// return $key;
// }
// }
// )
// );
// print "DEFAULT ACL: <br>".$backend->print_ar($result)."<br>";
// DEPRICATED CALL
// $backend->adbSetACL($login->loginGetAcl());
}
print "THIS HOST: " . HOST_NAME . ", with PROTOCOL: " . HOST_PROTOCOL . " is running SSL: " . HOST_SSL . "<br>"; print "THIS HOST: " . HOST_NAME . ", with PROTOCOL: " . HOST_PROTOCOL . " is running SSL: " . HOST_SSL . "<br>";
print "DIR: " . DIR . "<br>"; print "DIR: " . DIR . "<br>";
print "BASE: " . BASE . "<br>"; print "BASE: " . BASE . "<br>";
@@ -205,6 +196,9 @@ print "HOST: " . HOST_NAME . " => DB HOST: " . DB_CONFIG_NAME . " => " . Support
print "DS is: " . DIRECTORY_SEPARATOR . "<br>"; print "DS is: " . DIRECTORY_SEPARATOR . "<br>";
print "SERVER HOST: " . $_SERVER['HTTP_HOST'] . "<br>"; print "SERVER HOST: " . $_SERVER['HTTP_HOST'] . "<br>";
print "<div>READ _SERVER ARRAY:</div>";
print Support::dumpVar(array_map('htmlentities', $_SERVER));
print "</body></html>"; print "</body></html>";
# __END__ # __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -28,8 +28,6 @@ $log = new CoreLibs\Logging\Logging([
$_phpv = new CoreLibs\Check\PhpVersion(); $_phpv = new CoreLibs\Check\PhpVersion();
$phpv_class = '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'; $PAGE_NAME = 'TEST CLASS: PHP VERSION';
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>"; print "<html><head><title>" . $PAGE_NAME . "</title></head>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -38,13 +38,21 @@ $key_length = 10;
$key_length_b = 5; $key_length_b = 5;
$key_lenght_long = 64; $key_lenght_long = 64;
print "S::RANDOMKEYGEN(auto): " . RandomKey::randomKeyGen() . "<br>"; print "S::RANDOMKEYGEN(auto): " . RandomKey::randomKeyGen() . "<br>";
print "S::SETRANDOMKEYLENGTH($key_length): " . RandomKey::setRandomKeyLength($key_length) . "<br>"; // print "S::SETRANDOMKEYLENGTH($key_length): " . RandomKey::setRandomKeyLength($key_length) . "<br>";
print "S::RANDOMKEYGEN($key_length): " . RandomKey::randomKeyGen() . "<br>"; print "S::RANDOMKEYGEN($key_length): " . RandomKey::randomKeyGen($key_length) . "<br>";
print "S::RANDOMKEYGEN($key_length_b): " . RandomKey::randomKeyGen($key_length_b) . "<br>"; print "S::RANDOMKEYGEN($key_length_b): " . RandomKey::randomKeyGen($key_length_b) . "<br>";
print "S::RANDOMKEYGEN($key_length): " . RandomKey::randomKeyGen() . "<br>"; print "S::RANDOMKEYGEN($key_length): " . RandomKey::randomKeyGen($key_length) . "<br>";
print "S::RANDOMKEYGEN($key_lenght_long): " . RandomKey::randomKeyGen($key_lenght_long) . "<br>"; print "S::RANDOMKEYGEN($key_lenght_long): " . RandomKey::randomKeyGen($key_lenght_long) . "<br>";
print "S::RANDOMKEYGEN($key_lenght_long, list data): "
. RandomKey::randomKeyGen($key_lenght_long, ['A', 'B', 'C'], ['7', '8', '9']) . "<br>";
print "S::RANDOMKEYGEN(auto): " . RandomKey::randomKeyGen() . "<br>";
print "===<Br>";
$_array = new CoreLibs\Create\RandomKey(); $_array = new CoreLibs\Create\RandomKey();
print "C->RANDOMKEYGEN(auto): " . $_array->randomKeyGen() . "<br>"; print "C->RANDOMKEYGEN(default): " . $_array->randomKeyGen() . "<br>";
print "===<Br>";
// CHANGE key characters
$_array = new CoreLibs\Create\RandomKey(['A', 'F', 'B'], ['1', '5', '9']);
print "C->RANDOMKEYGEN(pre set): " . $_array->randomKeyGen() . "<br>";
print "</body></html>"; print "</body></html>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -34,10 +34,12 @@ print '<div><h1>' . $PAGE_NAME . '</h1></div>';
print "ALREADY from config.php: " . \CoreLibs\Debug\Support::printAr($_ENV) . "<br>"; print "ALREADY from config.php: " . \CoreLibs\Debug\Support::printAr($_ENV) . "<br>";
// This is now in \gullevek\dotenv\DotEnv::readEnvFile(...)
// test .env in local // test .env in local
$status = \CoreLibs\Get\DotEnv::readEnvFile('.', 'test.env'); /* $status = \CoreLibs\Get\DotEnv::readEnvFile('.', 'test.env');
print "test.env: STATUS: " . $status . "<br>"; print "test.env: STATUS: " . $status . "<br>";
print "AFTER reading test.env file: " . \CoreLibs\Debug\Support::printAr($_ENV) . "<br>"; print "AFTER reading test.env file: " . \CoreLibs\Debug\Support::printAr($_ENV) . "<br>"; */
print "</body></html>"; print "</body></html>";
// ;; // ;;

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
/** /**
* Undocumented function * Undocumented function
@@ -45,8 +45,8 @@ $log = new CoreLibs\Logging\Logging([
'log_file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true, 'log_per_date' => true,
]); ]);
use CoreLibs\Debug\Support;
use CoreLibs\Create\Session; use CoreLibs\Create\Session;
$session = new Session();
$PAGE_NAME = 'TEST CLASS: SESSION'; $PAGE_NAME = 'TEST CLASS: SESSION';
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
@@ -56,117 +56,122 @@ print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$session_name = 'class-test-session'; $session_name = 'class-test-session';
print "Valid session name static check for '" . $session_name . "': "
. Support::prBl(Session::checkValidSessionName($session_name)) . "<br>";
$var = 'foo'; $var = 'foo';
$value = 'bar'; $value = 'bar';
$session = new Session($session_name);
foreach (['123', '123-123', '123abc'] as $_session_name) { foreach (['123', '123-123', '123abc'] as $_session_name) {
print "[UNSET] Session Name valid for " . $_session_name . ": " print "[UNSET] Session Name valid for '" . $_session_name . "': "
. ($session->checkValidSessionName($_session_name) ? 'Valid' : 'Invalid') . "<br>"; . ($session->checkValidSessionName($_session_name) ? 'Valid' : 'Invalid') . "<br>";
} }
echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "<br>"; echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "<br>";
print "[UNSET] Current session id: " . $session->getSessionId() . "<br>";
print "[UNSET] Current session name: " . $session->getSessionName() . "<br>";
print "[UNSET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>";
print "[UNSET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "<br>";
if (isset($_SESSION)) {
print "[UNSET] _SESSION is: set<br>";
} else {
print "[UNSET] _SESSION is: not set<br>";
}
#
print "[UNSET] To set session name valid: "
. ($session->checkValidSessionName($session_name) ? 'Valid' : 'Invalid') . "<br>";
try {
$session_id = $session->startSession($session_name);
print "[SET] Current session id: " . $session_id . "<br>";
} catch (\Exception $e) {
print "[FAILED] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>";
}
// set again
try {
$session_id = $session->startSession($session_name);
print "[2 SET] Current session id: " . $session_id . "<br>";
} catch (\Exception $e) {
print "[2 FAILED] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>";
}
print "[SET] Current session id: " . $session->getSessionId() . "<br>"; print "[SET] Current session id: " . $session->getSessionId() . "<br>";
print "[SET] Current session name: " . $session->getSessionName() . "<br>"; print "[SET] Current session name: " . $session->getSessionName() . "<br>";
print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>"; print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>";
print "[SET] Current session auto write close: " . ($session->checkAutoWriteClose() ? 'Yes' : 'No') . "<br>";
print "[SET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "<br>"; print "[SET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "<br>";
if (isset($_SESSION)) { if (isset($_SESSION)) {
print "[SET] _SESSION is: set<br>"; print "[SET] _SESSION is: set<br>";
} else { } else {
print "[SET] _SESSION is: not set<br>"; print "[SET] _SESSION is: not set<br>";
} }
#
if (!isset($_SESSION['counter'])) { if (!isset($_SESSION['counter'])) {
$_SESSION['counter'] = 0; $_SESSION['counter'] = 0;
} }
$_SESSION['counter']++; $_SESSION['counter']++;
print "[READ] A " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>"; print "[READ] A " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>";
$_SESSION[$var] = $value; $_SESSION[$var] = $value;
/** @phpstan-ignore-next-line nullCoalesce.offset */
print "[READ] B " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>"; print "[READ] B " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>";
print "[READ] Confirm " . $var . " is " . $value . ": " print "[READ] Confirm " . $var . " is " . $value . ": "
/** @phpstan-ignore-next-line equal.alwaysTrue, nullCoalesce.offset */
. (($_SESSION[$var] ?? '') == $value ? 'Matching' : 'Not matching') . "<br>"; . (($_SESSION[$var] ?? '') == $value ? 'Matching' : 'Not matching') . "<br>";
// test set wrappers methods // test set wrappers methods
$session->setS('setwrap', 'YES, method set _SESSION var'); $session->set('setwrap', 'YES, method set _SESSION var');
print "[READ WRAP] A setwrap: " . $session->getS('setwrap') . "<br>"; print "[READ WRAP] A setwrap: " . $session->get('setwrap') . "<br>";
print "[READ WRAP] Isset: " . ($session->issetS('setwrap') ? 'Yes' : 'No') . "<br>"; print "[READ WRAP] Isset: " . ($session->isset('setwrap') ? 'Yes' : 'No') . "<br>";
$session->unsetS('setwrap'); $session->unset('setwrap');
print "[READ WRAP] unset setwrap: " . $session->getS('setwrap') . "<br>"; print "[READ WRAP] unset setwrap: " . $session->get('setwrap') . "<br>";
print "[READ WRAP] unset Isset: " . ($session->issetS('setwrap') ? 'Yes' : 'No') . "<br>"; print "[READ WRAP] unset Isset: " . ($session->isset('setwrap') ? 'Yes' : 'No') . "<br>";
// test __get/__set $session->set('foo 3', 'brause');
$session->setwrap = 'YES, magic set _SESSION var'; /** @phpstan-ignore-line GET/SETTER */ // set many
print "[READ MAGIC] A setwrap: " . ($session->setwrap ?? '') . "<br>"; $session->setMany([
print "[READ MAGIC] Isset: " . (isset($session->setwrap) ? 'Yes' : 'No') . "<br>"; 'foo 1' => 'bar',
unset($session->setwrap); 'foo 2' => 'kamel',
print "[READ MAGIC] unset setwrap: " . ($session->setwrap ?? '') . "<br>"; ]);
print "[READ MAGIC] unset Isset: " . (isset($session->setwrap) ? 'Yes' : 'No') . "<br>"; print "[READ MANY]: " . Support::printAr($session->getMany(['foo 1', 'foo 2'])) . "<br>";
try {
$session->setMany([ /** @phpstan-ignore-line deliberate error */
'ok' => 'ok',
'a123' => 'bar',
1 => 'bar',
]);
} catch (\Exception $e) {
print "FAILED] Session manySet failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><br>";
}
try {
$session->set('123', 'illigal');
} catch (\Exception $e) {
print "FAILED] Session set failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><br>";
}
print "<hr>";
// differnt session name // differnt session name
$session_name = 'class-test-session-ALT'; $session_name = 'class-test-session-ALT';
try { try {
$session_id = $session->startSession($session_name); $session_alt = new Session($session_name);
print "[3 SET] Current session id: " . $session_id . "<br>"; print "[3 SET] Current session id: " . $session_alt->getSessionId() . "<br>";
print "[SET AGAIN] Current session id: " . $session_alt->getSessionId() . "<br>";
} catch (\Exception $e) { } catch (\Exception $e) {
print "[3 FAILED] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>"; print "[3 FAILED] Session start failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><br>";
} }
print "[SET AGAIN] Current session id: " . $session->getSessionId() . "<br>";
print "[ALL SESSION]: " . \CoreLibs\Debug\Support::printAr($_SESSION) . "<br>";
print "[ALL SESSION]: " . Support::printAr($_SESSION) . "<br>";
// close session // close session
$session->writeClose(); $session->writeClose();
// will never be written // will never be written
$_SESSION['will_never_be_written'] = 'empty'; $_SESSION['will_never_be_written'] = 'empty';
// auto open session if closed to write
$session->set('auto_write_session', 'Some value');
// restart session
$session->restartSession();
$_SESSION['this_will_be_written'] = 'not empty';
// open again // open again with same name
$session_name = 'class-test-session'; $session_name = 'class-test-session';
try { try {
$session_id = $session->startSession($session_name); $session_alt = new Session($session_name, ['auto_write_close' => true]);
print "[4 SET] Current session id: " . $session_id . "<br>"; print "[4 SET] Current session id: " . $session_alt->getSessionId() . "<br>";
print "[4 SET] Current session auto write close: " . ($session_alt->checkAutoWriteClose() ? 'Yes' : 'No') . "<br>";
print "[START AGAIN] Current session id: " . $session_alt->getSessionId() . "<br>";
$session_alt->set('alt_write_auto_close', 'set auto');
// below is deprecated
// $session_alt->do_not_do_this = 'foo bar auto set';
} catch (\Exception $e) { } catch (\Exception $e) {
print "[4 FAILED] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>"; print "[4 FAILED] Session start failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><br>";
} }
print "[START AGAIN] Current session id: " . $session->getSessionId() . "<br>";
$_SESSION['will_be_written_again'] = 'Full'; $_SESSION['will_be_written_again'] = 'Full';
print "[ALL SESSION]: " . Support::printAr($_SESSION) . "<br>";
// close session // close session
$session->writeClose(); $session->writeClose();
// invalid // invalid
$session_name = '123'; $session_name = '123';
try { try {
$session_id = $session->startSession($session_name); $session_bad = new Session($session_name);
print "[5 SET] Current session id: " . $session_id . "<br>"; print "[5 SET] Current session id: " . $session_bad->getSessionId() . "<br>";
} catch (\Exception $e) { } catch (\Exception $e) {
print "[5 FAILED] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>"; print "[5 FAILED] Session start failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><br>";
} }
print "[BAD NAME] Current session id: " . $session->getSessionId() . "<br>";
print "[BAD NAME] Current session name: " . $session->getSessionName() . "<br>";
print "[BAD NAME] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>";
print "[BAD NAME] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "<br>";
print "</body></html>"; print "</body></html>";

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
/** /**
* Undocumented function * Undocumented function
@@ -46,7 +46,6 @@ $log = new CoreLibs\Logging\Logging([
'log_per_date' => true, 'log_per_date' => true,
]); ]);
use CoreLibs\Create\Session; use CoreLibs\Create\Session;
$session = new Session();
$PAGE_NAME = 'TEST CLASS: SESSION (READ)'; $PAGE_NAME = 'TEST CLASS: SESSION (READ)';
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
@@ -56,32 +55,22 @@ print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$session_name = 'class-test-session'; $session_name = 'class-test-session';
$session = new Session($session_name);
// $session_name = ''; // $session_name = '';
$var = 'foo'; $var = 'foo';
$value = 'bar'; $value = 'bar';
echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "<br>"; echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "<br>";
print "[UNSET] Current session id: " . $session->getSessionId() . "<br>"; print "[SET] Current session id: " . $session->getSessionId() . "<br>";
print "[UNSET] Current session name: " . $session->getSessionName() . "<br>"; print "[SET] Current session name: " . $session->getSessionName() . "<br>";
print "[UNSET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>"; print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>";
print "[UNSET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "<br>"; print "[SET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "<br>";
print "[READ] " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>"; print "[READ] " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>";
// start
try {
$session_id = $session->startSession($session_name);
print "[1] Current session id: " . $session_id . "<br>";
} catch (\Exception $e) {
print "[1] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>";
}
// set again // set again
try { print "[2] Restarted session: " . \CoreLibs\Debug\Support::prBl($session->restartSession()) . "<br>";
$session_id = $session->startSession($session_name);
print "[2] Current session id: " . $session_id . "<br>";
} catch (\Exception $e) {
print "[2] Session start failed:<br>" . $e->getMessage() . "<br>" . $e . "<br>";
}
print "[SET] Current session id: " . $session->getSessionId() . "<br>"; print "[SET] Current session id: " . $session->getSessionId() . "<br>";
print "[SET] Current session name: " . $session->getSessionName() . "<br>"; print "[SET] Current session name: " . $session->getSessionName() . "<br>";
print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>"; print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "<br>";

View File

@@ -4,9 +4,11 @@
* @phan-file-suppress PhanTypeSuspiciousStringExpression * @phan-file-suppress PhanTypeSuspiciousStringExpression
*/ */
// FIXME: Smarty Class must be updated for PHP 8.4
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -33,6 +35,7 @@ $l10n = new \CoreLibs\Language\L10n(
); );
$smarty = new CoreLibs\Template\SmartyExtend( $smarty = new CoreLibs\Template\SmartyExtend(
$l10n, $l10n,
$log,
CACHE_ID, CACHE_ID,
COMPILE_ID, COMPILE_ID,
); );
@@ -45,6 +48,7 @@ $adm = new CoreLibs\Admin\Backend(
); );
$adm->DATA['adm_set'] = 'SET from admin class'; $adm->DATA['adm_set'] = 'SET from admin class';
$PAGE_NAME = 'TEST CLASS: SMARTY'; $PAGE_NAME = 'TEST CLASS: SMARTY';
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>"; print "<html><head><title>" . $PAGE_NAME . "</title></head>";

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -14,6 +14,9 @@ require 'config.php';
$LOG_FILE_ID = 'classTest-string'; $LOG_FILE_ID = 'classTest-string';
ob_end_flush(); ob_end_flush();
use CoreLibs\Convert\Strings;
use CoreLibs\Debug\Support as DgS;
$log = new CoreLibs\Logging\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
@@ -29,6 +32,7 @@ print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>'; print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$split = '4-4-4'; $split = '4-4-4';
$split_length = 4;
$test_strings = [ $test_strings = [
'13', '13',
'1234', '1234',
@@ -40,20 +44,59 @@ $test_strings = [
]; ];
foreach ($test_strings as $string) { foreach ($test_strings as $string) {
print "Convert: $string with $split to: " print "A) Convert: $string with $split to: "
. \CoreLibs\Convert\Strings::splitFormatString($string, $split) . Strings::splitFormatString($string, $split)
. "<br>"; . "<br>";
try {
print "B) Convert: $string with $split_length to: "
. Strings::splitFormatStringFixed($string, $split_length)
. "<br>";
} catch (Exception $e) {
print "Split not possible: " . $e->getMessage() . "<br>";
}
} }
$split = '2_2'; $split = '2_2';
$split_length = 2;
$string = '1234'; $string = '1234';
print "Convert: $string with $split to: " print "A) Convert: $string with $split to: "
. \CoreLibs\Convert\Strings::splitFormatString($string, $split) . Strings::splitFormatString($string, $split)
. "<br>";
print "B) Convert: $string with $split_length to: "
. Strings::splitFormatStringFixed($string, $split_length, "_")
. "<br>"; . "<br>";
$split = '2-2'; $split = '2-2';
$string = 'あいうえ'; $string = 'あいうえ';
print "Convert: $string with $split to: " try {
. \CoreLibs\Convert\Strings::splitFormatString($string, $split) print "Convert: $string with $split to: "
. Strings::splitFormatString($string, $split)
. "<br>";
} catch (\Exception $e) {
print "Cannot split string: " . $e->getMessage() . "<br>";
}
print "B) Convert: $string with $split_length to: "
. Strings::splitFormatStringFixed($string, $split_length, "-")
. "<br>";
$string = 'ABCD12345568ABC13';
$format = '2-4_5-2#4';
$output = 'AB-CD12_34556-8A#BC13';
print "A) Convert: $string with $format to: "
. Strings::splitFormatString($string, $format)
. "<br>";
// try other split calls
$string = "ABCDE";
$split_length = 2;
$split_char = "-=-";
print "Convert: $string with $split_length / $split_char to: "
. Strings::splitFormatStringFixed($string, $split_length, $split_char)
. "<br>";
$string = "あいうえお";
$split_length = 2;
$split_char = "-=-";
print "Convert: $string with $split_length / $split_char to: "
. Strings::splitFormatStringFixed($string, $split_length, $split_char)
. "<br>"; . "<br>";
$test_splits = [ $test_splits = [
@@ -63,9 +106,40 @@ $test_splits = [
'2-3-4', '2-3-4',
]; ];
foreach ($test_splits as $split) { foreach ($test_splits as $split) {
print "$split with count: " . \CoreLibs\Convert\Strings::countSplitParts($split) . "<br>"; print "$split with count: " . Strings::countSplitParts($split) . "<br>";
} }
// check char list in list
$needle = "abc";
$haystack = "abcdefg";
print "Needle: " . $needle . ", Haysteck: " . $haystack . ": "
. DgS::prBl(Strings::allCharsInSet($needle, $haystack)) . "<br>";
$needle = "abcz";
print "Needle: " . $needle . ", Haysteck: " . $haystack . ": "
. DgS::prBl(Strings::allCharsInSet($needle, $haystack)) . "<br>";
print "Combined strings A: "
. Strings::buildCharStringFromLists(['A', 'B', 'C'], ['0', '1', '2']) . "<br>";
print "Combined strings B: "
. Strings::buildCharStringFromLists([['F'], ['G'], 'H'], [['5', ['6']], ['0'], '1', '2']) . "<br>";
$input_string = "AaBbCc";
print "Unique: " . Strings::removeDuplicates($input_string) . "<br>";
print "Unique: " . Strings::removeDuplicates(strtolower($input_string)) . "<br>";
$regex_string = "/^[A-z]$/";
print "Regex is: " . $regex_string . ": " . DgS::prBl(Strings::isValidRegex($regex_string)) . "<br>";
$regex_string = "'//test{//'";
print "Regex is: " . $regex_string . ": " . DgS::prBl(Strings::isValidRegex($regex_string)) . "<br>";
print "Regex is: " . $regex_string . ": " . DgS::printAr(Strings::validateRegex($regex_string)) . "<br>";
$regex_string = "/^[A-z";
print "Regex is: " . $regex_string . ": " . DgS::prBl(Strings::isValidRegex($regex_string)) . "<br>";
print "[A] LAST PREGE ERROR: " . preg_last_error() . " -> "
. (Strings::PREG_ERROR_MESSAGES[preg_last_error()] ?? '-') . "<br>";
$preg_error = Strings::isValidRegex($regex_string);
print "[B] LAST PREGE ERROR: " . preg_last_error() . " -> "
. Strings::getLastRegexErrorString() . " -> " . preg_last_error_msg() . "<br>";
print "</body></html>"; print "</body></html>";
// __END__ // __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -41,7 +41,7 @@ print "GETPAGENAME(0): " . System::getPageName() . "<br>";
print "GETPAGENAME(1): " . System::getPageName(System::NO_EXTENSION) . "<br>"; print "GETPAGENAME(1): " . System::getPageName(System::NO_EXTENSION) . "<br>";
print "GETPAGENAME(2): " . System::getPageName(System::FULL_PATH) . "<br>"; print "GETPAGENAME(2): " . System::getPageName(System::FULL_PATH) . "<br>";
print "System::getPageNameArray():<br>"; print "System::getPageNameArray():<br>";
print "GETPAGENAMEARRAY: " . \CoreLibs\Debug\Support::printAr(System::getPageNameArray()) . "<br>"; print "GETPAGENAMEARRAY: " . DgS::printAr(System::getPageNameArray()) . "<br>";
// seting errro codes file upload // seting errro codes file upload
print "System::fileUploadErrorMessage():<br>"; print "System::fileUploadErrorMessage():<br>";
print "FILEUPLOADERRORMESSAGE(): " . System::fileUploadErrorMessage(-1) . "<br>"; print "FILEUPLOADERRORMESSAGE(): " . System::fileUploadErrorMessage(-1) . "<br>";
@@ -51,4 +51,6 @@ print "FILEUPLOADERRORMESSAGE(UPLOAD_ERR_CANT_WRITE): "
print "System::checkCLI():<br>"; print "System::checkCLI():<br>";
print "Are we in an CLI: " . (System::checkCLI() ? 'Yes' : 'No') . "<br>"; print "Are we in an CLI: " . (System::checkCLI() ? 'Yes' : 'No') . "<br>";
print "Get Addresses: " . DgS::printAr(System::getIpAddresses()) . "<br>";
print "</body></html>"; print "</body></html>";

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -52,6 +52,16 @@ print "S:UNIQID (512): " . Uids::uniqId(512) . "<br>";
// uniq ids // uniq ids
print "UNIQU ID SHORT : " . Uids::uniqIdShort() . "<br>"; print "UNIQU ID SHORT : " . Uids::uniqIdShort() . "<br>";
print "UNIQU ID LONG : " . Uids::uniqIdLong() . "<br>"; print "UNIQU ID LONG : " . Uids::uniqIdLong() . "<br>";
// validate
$uuidv4 = Uids::uuidv4();
if (!Uids::validateUuuidv4($uuidv4)) {
print "Invalid UUIDv4: " . $uuidv4 . "<br>";
} else {
print "Valid UUIDv4: " . $uuidv4 . "<br>";
}
if (!Uids::validateUuuidv4("foobar")) {
print "Invalid UUIDv4: hard coded<Br>";
}
// DEPRECATED // DEPRECATED
/* print "D/UUIDV4: ".$basic->uuidv4()."<br>"; /* print "D/UUIDV4: ".$basic->uuidv4()."<br>";

View File

@@ -0,0 +1,361 @@
<?php // phpcs:ignore warning
/**
* @phan-file-suppress PhanTypeSuspiciousStringExpression
*/
declare(strict_types=1);
error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start();
// basic class test file
define('USE_DATABASE', false);
// sample config
require 'config.php';
// define log file id
$LOG_FILE_ID = 'classTest-urlrequests';
ob_end_flush();
use CoreLibs\UrlRequests\Curl;
$log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG,
'log_file_id' => $LOG_FILE_ID,
'log_per_date' => true,
]);
$PAGE_NAME = 'TEST CLASS: URL REQUESTS CURL';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";
print "<body>";
print '<div><a href="class_test.php">Class Test Master</a></div>';
print '<div><h1>' . $PAGE_NAME . '</h1></div>';
$client = new Curl();
print "<hr>";
$data = $client->get(
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=get_a',
[
'headers' => [
'test-header' => 'ABC',
'info-request-type' => '_GET',
'Funk-pop' => 'Semlly god'
],
'query' => ['foo' => 'BAR']
]
);
print "_GET RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->request(
'get',
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=get_a',
);
print "_GET RESPONSE, nothing set: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
try {
$data = $client->request(
'get',
'soba54.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=get_a',
);
print "_GET RESPONSE, nothing set, invalid URL: <pre>" . print_r($data, true) . "</pre>";
} catch (Exception $e) {
print "Exception: <pre>" . print_r($e, true) . "</pre><br>";
}
print "<hr>";
$data = $client->request(
"get",
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/'
. 'trunk/www/admin/UrlRequests.target.php'
. '?other=get_a',
[
"headers" => [
'test-header' => 'ABC',
'info-request-type' => '_GET',
'Funk-pop' => 'Semlly god'
],
"query" => ['foo' => 'BAR'],
],
);
print "[request] _GET RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->post(
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=post_a',
[
'body' => ['payload' => 'data post'],
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_POST',
],
'query' => ['foo' => 'BAR post'],
]
);
print "_POST RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->request(
"post",
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=post_a',
[
"body" => ['payload' => 'data post', 'request' => 'I am the request body'],
"headers" => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_POST',
],
"query" => ['foo' => 'BAR post'],
]
);
print "[request] _POST RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->request(
"post",
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=post_a',
[
"body" => 'string body here',
"headers" => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_POST',
],
"query" => ['foo' => 'BAR post'],
]
);
print "[request|string body] _POST RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->put(
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=put_a',
[
"body" => ['payload' => 'data put'],
"headers" => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_PUT',
],
'query' => ['foo' => 'BAR put'],
]
);
print "_PUT RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->patch(
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=patch_a',
[
"body" => ['payload' => 'data patch'],
"headers" => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_PATCH',
],
'query' => ['foo' => 'BAR patch'],
]
);
print "_PATCH RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->delete(
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=delete_no_body_a',
[
"body" => null,
"headers" => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_DELETE',
],
"query" => ['foo' => 'BAR delete'],
]
);
print "_DELETE RESPONSE: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
$data = $client->delete(
'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/UrlRequests.target.php'
. '?other=delete_body_a',
[
"body" => ['payload' => 'data delete'],
"headers" => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'test-header' => 'ABC',
'info-request-type' => '_DELETE',
],
"query" => ['foo' => 'BAR delete'],
]
);
print "_DELETE RESPONSE BODY: <pre>" . print_r($data, true) . "</pre>";
print "<hr>";
try {
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/foo',
"headers" => [
'DEFAULT-master' => 'master-header',
'default-header' => 'uc-get',
'default-remove' => 'will be removed',
'default-remove-array' => ['a', 'b'],
'default-remove-array-part' => ['c', 'd'],
'default-remove-array-part-alt' => ['c', 'd', 'e'],
'default-overwrite' => 'will be overwritten',
'default-add' => 'will be added',
],
'query' => [
'global-p' => 'glob'
]
]);
print "CONFIG: <pre>" . print_r($uc->getConfig(), true) . "</pre>";
$uc->removeHeaders(['default-remove' => '']);
$uc->removeHeaders(['default-remove-array' => ['a', 'b']]);
$uc->removeHeaders(['default-remove-array-part' => 'c']);
$uc->removeHeaders(['default-remove-array-part-alt' => ['c', 'd']]);
$uc->setHeaders(['default-new' => 'Something new']);
$uc->setHeaders(['default-overwrite' => 'Something Overwritten']);
$uc->setHeaders(['default-add' => 'Something Added'], true);
print "CONFIG: <pre>" . print_r($uc->getConfig(), true) . "</pre>";
$data = $uc->request(
'get',
'UrlRequests.target.php',
[
'headers' => [
'call-header' => 'call-get',
'default-header' => 'overwrite-uc-get',
'X-Foo' => ['bar', 'baz'],
],
'query' => [
'other' => 'get_a',
],
]
);
print "[uc] _GET RESPONSE, nothing set: <pre>" . print_r($data, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
} catch (Exception $e) {
print "Exception: <pre>" . print_r(json_decode($e->getMessage(), true), true) . "</pre><br>";
}
print "<hr>";
try {
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/',
"http_errors" => false,
"headers" => [
"Authorization" => "schmalztiegel",
"RunAuthTest" => "yes",
]
]);
$response = $uc->get('UrlRequests.target.php');
print "AUTH REQUEST: <pre>" . print_r($response, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
} catch (Exception $e) {
print "Exception: <pre>" . print_r(json_decode($e->getMessage(), true), true) . "</pre><br>";
}
print "AUTH REQUEST WITH EXCEPTION:<br>";
try {
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/',
"http_errors" => true,
"headers" => [
"Authorization" => "schmalztiegel",
"RunAuthTest" => "yes",
]
]);
$response = $uc->get('UrlRequests.target.php');
print "AUTH REQUEST: <pre>" . print_r($response, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
} catch (Exception $e) {
print "Exception: <pre>" . print_r(json_decode($e->getMessage(), true), true) . "</pre><br>";
}
print "AUTH REQUEST WITH EXCEPTION (UNSET):<br>";
try {
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/',
"http_errors" => true,
"headers" => [
"Authorization" => "schmalztiegel",
"RunAuthTest" => "yes",
]
]);
$response = $uc->get('UrlRequests.target.php', ['http_errors' => false]);
print "AUTH REQUEST (UNSET): <pre>" . print_r($response, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
} catch (Exception $e) {
print "Exception: <pre>" . print_r(json_decode($e->getMessage(), true), true) . "</pre><br>";
}
print "AUTH REQUEST HEADER SET:<br>";
try {
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/',
"auth" => ["user", "pass", "basic"],
"headers" => [
"Authorization" => "schmalztiegel",
"RunAuthTest" => "yes",
]
]);
$response = $uc->get('UrlRequests.target.php');
print "AUTH REQUEST (HEADER): <pre>" . print_r($response, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
} catch (Exception $e) {
print "Exception: <pre>" . print_r(json_decode($e->getMessage(), true), true) . "</pre><br>";
}
print "<hr>";
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/',
"headers" => [
"header-one" => "one"
]
]);
$response = $uc->get('UrlRequests.target.php', ["headers" => null, "query" => ["test" => "one-test"]]);
print "HEADER RESET REQUEST: <pre>" . print_r($response, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
print "<hr>";
$uc = new Curl([
"base_uri" => 'https://soba.egplusww.jp/developers/clemens/core_data/php_libraries/trunk/www/admin/',
"headers" => [
'bar' => 'foo:bar'
]
]);
$response = $uc->get('UrlRequests.target.php');
print "HEADER SET TEST REQUEST: <pre>" . print_r($response, true) . "</pre>";
print "[uc] SENT URL: " . $uc->getUrlSent() . "<br>";
print "[uc] SENT URL PARSED: <pre>" . print_r($uc->getUrlParsedSent(), true) . "</pre>";
print "[uc] SENT HEADERS: <pre>" . print_r($uc->getHeadersSent(), true) . "</pre>";
print "</body></html>";
// __END__

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -0,0 +1,5 @@
<?php
// empty file for add and remove test
// __END__

View File

@@ -2,12 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
$DEBUG_ALL_OVERRIDE = 0; // set to 1 to debug on live/remote server locations $DEBUG_LEVEL = \CoreLibs\Logging\Logger\Level::Debug;
$DEBUG_ALL = 1;
$PRINT_ALL = 1;
$DB_DEBUG = 1;
if ($DEBUG_ALL) { if ($DEBUG_LEVEL->name == 'Debug') {
error_reporting(E_ALL); error_reporting(E_ALL);
} }

View File

@@ -6,7 +6,7 @@
declare(strict_types=1); declare(strict_types=1);
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR); error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();

View File

@@ -1 +1 @@
../../4dev/tests/dotenv/test.env ../../4dev/tests/Get/dotenv/test.env

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<head>
<title>JavaScript Test</title>
<script type="text/javascript" src="layout/javascript/jquery.min.js"></script>
<script type="text/javascript" src="layout/javascript/translateTest-ja_JP.UTF-8.js"></script>
<script type="text/javascript" src="layout/javascript/utils.min.js"></script>
</head>
<body>
<div>
<h1>JavaScript tests</h1>
<div id="test-div">
</div>
</div>
</body>
<script languagae="JavaScript">
document.addEventListener('DOMContentLoaded', function() {
console.log('MAIN PAGE LOADED');
// console.log('Random: %o', mh.randomIdF());
console.log('Random: %o', randomIdF());
console.log("GW: %o", getWindowSize());
let bytes = 1021152;
console.log('FB: %o', formatBytes(bytes));
console.log('FBL: %o', formatBytesLong(bytes));
console.log('TR: %s', l10n.__('Original'));
console.log('TR: %s', l10n.__('Not exists'));
setCenter('test-div', true, true);
ClearCall();
overlayBoxShow();
actionIndicatorShow('testSmarty');
setTimeout(function() {
console.log('Waiting dummy ...');
actionIndicatorHide('testSmarty');
ClearCall();
}, 2000);
});
</script>

View File

@@ -4,12 +4,7 @@
declare(strict_types=1); declare(strict_types=1);
$DEBUG_ALL_OVERRIDE = false; // set to 1 to debug on live/remote server locations error_reporting(E_ALL | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
$DEBUG_ALL = true;
$PRINT_ALL = true;
$DB_DEBUG = true;
error_reporting(E_ALL | E_STRICT | E_ERROR | E_WARNING | E_PARSE | E_COMPILE_ERROR);
ob_start(); ob_start();
@@ -23,15 +18,10 @@ $SET_SESSION_NAME = EDIT_SESSION_NAME;
// init login & backend class // init login & backend class
$session = new CoreLibs\Create\Session($SET_SESSION_NAME); $session = new CoreLibs\Create\Session($SET_SESSION_NAME);
$log = new CoreLibs\Debug\Logging([ $log = new CoreLibs\Logging\Logging([
'log_folder' => BASE . LOG, 'log_folder' => BASE . LOG,
'file_id' => $LOG_FILE_ID, 'log_file_id' => $LOG_FILE_ID,
// add file date 'log_per_date' => true,
'print_file_date' => true,
// set debug and print flags
'debug_all' => $DEBUG_ALL,
'echo_all' => $ECHO_ALL ?? false,
'print_all' => $PRINT_ALL,
]); ]);
$db = new CoreLibs\DB\IO(DB_CONFIG, $log); $db = new CoreLibs\DB\IO(DB_CONFIG, $log);
$login = new CoreLibs\ACL\Login( $login = new CoreLibs\ACL\Login(
@@ -57,7 +47,7 @@ $l10n = new \CoreLibs\Language\L10n(
); );
print "<!DOCTYPE html>"; print "<!DOCTYPE html>";
print "<html><head><title>GROUP TESTER</title><head>"; print "<html><head><title>GROUP TESTER</title></head>";
print "<body>"; print "<body>";
print '<form method="post" name="loginlogout">'; print '<form method="post" name="loginlogout">';

61
www/composer.lock generated
View File

@@ -12,15 +12,19 @@
"dist": { "dist": {
"type": "path", "type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All", "url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
"reference": "3eb122959045f8de10f9dd35e6632199021752b8" "reference": "f765f50350a6364ba36d832ed5acfdb4b3c78143"
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"psr/log": "^3.0@dev" "psr/log": "^3.0@dev"
}, },
"require-dev": { "require-dev": {
"egrajp/smarty-extended": "^4.3", "egrajp/smarty-extended": "^5.4",
"gullevek/dotenv": "dev-master", "gullevek/dotenv": "dev-master",
"phan/phan": "^5.4",
"phpstan/phpdoc-parser": "^2.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9"
}, },
"type": "library", "type": "library",
@@ -39,6 +43,13 @@
} }
], ],
"description": "CoreLibs in a composer package", "description": "CoreLibs in a composer package",
"keywords": [
"corelib",
"database",
"logging",
"templating",
"tools"
],
"transport-options": { "transport-options": {
"symlink": false, "symlink": false,
"relative": false "relative": false
@@ -47,11 +58,23 @@
{ {
"name": "egrajp/smarty-extended", "name": "egrajp/smarty-extended",
"version": "4.5.2", "version": "4.5.2",
"source": {
"type": "git",
"url": "https://git.egplusww.jp/Composer/Smarty-Extended",
"reference": "4.5.2"
},
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://git.egplusww.jp/api/packages/Composer/composer/files/egrajp%2Fsmarty-extended/4.5.2/egrajp-smarty-extended.4.5.2.zip", "url": "https://git.egplusww.jp/api/packages/Composer/composer/files/egrajp%2Fsmarty-extended/4.5.2/egrajp-smarty-extended.4.5.2.zip",
"shasum": "a2c67a5047aad349a2cfa54240a44da449df9c4c" "shasum": "a2c67a5047aad349a2cfa54240a44da449df9c4c"
}, },
"require": {
"ext-mbstring": "*",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"egrajp/corelibs-composer-all": "^9"
},
"type": "library", "type": "library",
"autoload": { "autoload": {
"classmap": [ "classmap": [
@@ -76,16 +99,16 @@
}, },
{ {
"name": "gullevek/dotenv", "name": "gullevek/dotenv",
"version": "v2.0.8", "version": "v2.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/gullevek/dotEnv.git", "url": "https://github.com/gullevek/dotEnv.git",
"reference": "e29f9fcd8853a09bb89b0eb8ee555b754ecee36e" "reference": "a7ade8648594c937ca24adb758eb5a702529cf70"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/gullevek/dotEnv/zipball/e29f9fcd8853a09bb89b0eb8ee555b754ecee36e", "url": "https://api.github.com/repos/gullevek/dotEnv/zipball/a7ade8648594c937ca24adb758eb5a702529cf70",
"reference": "e29f9fcd8853a09bb89b0eb8ee555b754ecee36e", "reference": "a7ade8648594c937ca24adb758eb5a702529cf70",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -93,7 +116,9 @@
}, },
"require-dev": { "require-dev": {
"phan/phan": "^5.4", "phan/phan": "^5.4",
"phpstan/phpstan": "^1.10", "phpstan/phpdoc-parser": "^2.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9"
}, },
"type": "library", "type": "library",
@@ -124,22 +149,22 @@
], ],
"support": { "support": {
"issues": "https://github.com/gullevek/dotEnv/issues", "issues": "https://github.com/gullevek/dotEnv/issues",
"source": "https://github.com/gullevek/dotEnv/tree/v2.0.8" "source": "https://github.com/gullevek/dotEnv/tree/v2.1.1"
}, },
"time": "2023-03-03T00:32:02+00:00" "time": "2024-11-18T11:10:09+00:00"
}, },
{ {
"name": "psr/log", "name": "psr/log",
"version": "3.0.0", "version": "3.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -174,9 +199,9 @@
"psr-3" "psr-3"
], ],
"support": { "support": {
"source": "https://github.com/php-fig/log/tree/3.0.0" "source": "https://github.com/php-fig/log/tree/3.0.2"
}, },
"time": "2021-07-14T16:46:02+00:00" "time": "2024-09-11T13:17:53+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
@@ -187,7 +212,7 @@
}, },
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": [], "platform": {},
"platform-dev": [], "platform-dev": {},
"plugin-api-version": "2.6.0" "plugin-api-version": "2.9.0"
} }

View File

@@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) {
echo $err; echo $err;
} }
} }
trigger_error( throw new RuntimeException($err);
$err,
E_USER_ERROR
);
} }
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';

View File

@@ -26,12 +26,23 @@ use Composer\Semver\VersionParser;
*/ */
class InstalledVersions class InstalledVersions
{ {
/**
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
* @internal
*/
private static $selfDir = null;
/** /**
* @var mixed[]|null * @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/ */
private static $installed; private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/** /**
* @var bool|null * @var bool|null
*/ */
@@ -309,6 +320,24 @@ class InstalledVersions
{ {
self::$installed = $data; self::$installed = $data;
self::$installedByVendor = array(); self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
* @return string
*/
private static function getSelfDir()
{
if (self::$selfDir === null) {
self::$selfDir = strtr(__DIR__, '\\', '/');
}
return self::$selfDir;
} }
/** /**
@@ -322,19 +351,27 @@ class InstalledVersions
} }
$installed = array(); $installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) { if (self::$canGetVendors) {
$selfDir = self::getSelfDir();
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) { if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir]; $installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) { } elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */ /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php'; $required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required; self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { $installed[] = $required;
self::$installed = $installed[count($installed) - 1]; if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
} }
} }
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
} }
} }
@@ -350,7 +387,7 @@ class InstalledVersions
} }
} }
if (self::$installed !== array()) { if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed; $installed[] = self::$installed;
} }

View File

@@ -7,35 +7,35 @@ namespace Composer\Autoload;
class ComposerStaticInit1b7cd5bacf2590b458d7a94400b505d4 class ComposerStaticInit1b7cd5bacf2590b458d7a94400b505d4
{ {
public static $prefixLengthsPsr4 = array ( public static $prefixLengthsPsr4 = array (
'g' => 'g' =>
array ( array (
'gullevek\\dotenv\\' => 16, 'gullevek\\dotenv\\' => 16,
'gullevek\\dotEnv\\' => 16, 'gullevek\\dotEnv\\' => 16,
), ),
'P' => 'P' =>
array ( array (
'Psr\\Log\\' => 8, 'Psr\\Log\\' => 8,
), ),
'C' => 'C' =>
array ( array (
'CoreLibs\\' => 9, 'CoreLibs\\' => 9,
), ),
); );
public static $prefixDirsPsr4 = array ( public static $prefixDirsPsr4 = array (
'gullevek\\dotenv\\' => 'gullevek\\dotenv\\' =>
array ( array (
0 => __DIR__ . '/..' . '/gullevek/dotenv/src', 0 => __DIR__ . '/..' . '/gullevek/dotenv/src',
), ),
'gullevek\\dotEnv\\' => 'gullevek\\dotEnv\\' =>
array ( array (
0 => __DIR__ . '/..' . '/gullevek/dotenv/src', 0 => __DIR__ . '/..' . '/gullevek/dotenv/src',
), ),
'Psr\\Log\\' => 'Psr\\Log\\' =>
array ( array (
0 => __DIR__ . '/..' . '/psr/log/src', 0 => __DIR__ . '/..' . '/psr/log/src',
), ),
'CoreLibs\\' => 'CoreLibs\\' =>
array ( array (
0 => __DIR__ . '/..' . '/egrajp/corelibs-composer-all/src', 0 => __DIR__ . '/..' . '/egrajp/corelibs-composer-all/src',
), ),

View File

@@ -7,15 +7,19 @@
"dist": { "dist": {
"type": "path", "type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All", "url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
"reference": "3eb122959045f8de10f9dd35e6632199021752b8" "reference": "f765f50350a6364ba36d832ed5acfdb4b3c78143"
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"psr/log": "^3.0@dev" "psr/log": "^3.0@dev"
}, },
"require-dev": { "require-dev": {
"egrajp/smarty-extended": "^4.3", "egrajp/smarty-extended": "^5.4",
"gullevek/dotenv": "dev-master", "gullevek/dotenv": "dev-master",
"phan/phan": "^5.4",
"phpstan/phpdoc-parser": "^2.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9"
}, },
"type": "library", "type": "library",
@@ -35,6 +39,13 @@
} }
], ],
"description": "CoreLibs in a composer package", "description": "CoreLibs in a composer package",
"keywords": [
"corelib",
"database",
"logging",
"templating",
"tools"
],
"transport-options": { "transport-options": {
"symlink": false, "symlink": false,
"relative": false "relative": false
@@ -45,11 +56,23 @@
"name": "egrajp/smarty-extended", "name": "egrajp/smarty-extended",
"version": "4.5.2", "version": "4.5.2",
"version_normalized": "4.5.2.0", "version_normalized": "4.5.2.0",
"source": {
"type": "git",
"url": "https://git.egplusww.jp/Composer/Smarty-Extended",
"reference": "4.5.2"
},
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://git.egplusww.jp/api/packages/Composer/composer/files/egrajp%2Fsmarty-extended/4.5.2/egrajp-smarty-extended.4.5.2.zip", "url": "https://git.egplusww.jp/api/packages/Composer/composer/files/egrajp%2Fsmarty-extended/4.5.2/egrajp-smarty-extended.4.5.2.zip",
"shasum": "a2c67a5047aad349a2cfa54240a44da449df9c4c" "shasum": "a2c67a5047aad349a2cfa54240a44da449df9c4c"
}, },
"require": {
"ext-mbstring": "*",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"egrajp/corelibs-composer-all": "^9"
},
"time": "2024-04-16T18:25:27+09:00", "time": "2024-04-16T18:25:27+09:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
@@ -76,17 +99,17 @@
}, },
{ {
"name": "gullevek/dotenv", "name": "gullevek/dotenv",
"version": "v2.0.8", "version": "v2.1.1",
"version_normalized": "2.0.8.0", "version_normalized": "2.1.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/gullevek/dotEnv.git", "url": "https://github.com/gullevek/dotEnv.git",
"reference": "e29f9fcd8853a09bb89b0eb8ee555b754ecee36e" "reference": "a7ade8648594c937ca24adb758eb5a702529cf70"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/gullevek/dotEnv/zipball/e29f9fcd8853a09bb89b0eb8ee555b754ecee36e", "url": "https://api.github.com/repos/gullevek/dotEnv/zipball/a7ade8648594c937ca24adb758eb5a702529cf70",
"reference": "e29f9fcd8853a09bb89b0eb8ee555b754ecee36e", "reference": "a7ade8648594c937ca24adb758eb5a702529cf70",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -94,10 +117,12 @@
}, },
"require-dev": { "require-dev": {
"phan/phan": "^5.4", "phan/phan": "^5.4",
"phpstan/phpstan": "^1.10", "phpstan/phpdoc-parser": "^2.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9"
}, },
"time": "2023-03-03T00:32:02+00:00", "time": "2024-11-18T11:10:09+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@@ -127,29 +152,29 @@
], ],
"support": { "support": {
"issues": "https://github.com/gullevek/dotEnv/issues", "issues": "https://github.com/gullevek/dotEnv/issues",
"source": "https://github.com/gullevek/dotEnv/tree/v2.0.8" "source": "https://github.com/gullevek/dotEnv/tree/v2.1.1"
}, },
"install-path": "../gullevek/dotenv" "install-path": "../gullevek/dotenv"
}, },
{ {
"name": "psr/log", "name": "psr/log",
"version": "3.0.0", "version": "3.0.2",
"version_normalized": "3.0.0.0", "version_normalized": "3.0.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.0.0" "php": ">=8.0.0"
}, },
"time": "2021-07-14T16:46:02+00:00", "time": "2024-09-11T13:17:53+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@@ -180,7 +205,7 @@
"psr-3" "psr-3"
], ],
"support": { "support": {
"source": "https://github.com/php-fig/log/tree/3.0.0" "source": "https://github.com/php-fig/log/tree/3.0.2"
}, },
"install-path": "../psr/log" "install-path": "../psr/log"
} }

View File

@@ -13,7 +13,7 @@
'egrajp/corelibs-composer-all' => array( 'egrajp/corelibs-composer-all' => array(
'pretty_version' => 'dev-development', 'pretty_version' => 'dev-development',
'version' => 'dev-development', 'version' => 'dev-development',
'reference' => '3eb122959045f8de10f9dd35e6632199021752b8', 'reference' => 'f765f50350a6364ba36d832ed5acfdb4b3c78143',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../egrajp/corelibs-composer-all', 'install_path' => __DIR__ . '/../egrajp/corelibs-composer-all',
'aliases' => array(), 'aliases' => array(),
@@ -31,25 +31,25 @@
'egrajp/smarty-extended' => array( 'egrajp/smarty-extended' => array(
'pretty_version' => '4.5.2', 'pretty_version' => '4.5.2',
'version' => '4.5.2.0', 'version' => '4.5.2.0',
'reference' => null, 'reference' => '4.5.2',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../egrajp/smarty-extended', 'install_path' => __DIR__ . '/../egrajp/smarty-extended',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'gullevek/dotenv' => array( 'gullevek/dotenv' => array(
'pretty_version' => 'v2.0.8', 'pretty_version' => 'v2.1.1',
'version' => '2.0.8.0', 'version' => '2.1.1.0',
'reference' => 'e29f9fcd8853a09bb89b0eb8ee555b754ecee36e', 'reference' => 'a7ade8648594c937ca24adb758eb5a702529cf70',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../gullevek/dotenv', 'install_path' => __DIR__ . '/../gullevek/dotenv',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'psr/log' => array( 'psr/log' => array(
'pretty_version' => '3.0.0', 'pretty_version' => '3.0.2',
'version' => '3.0.0.0', 'version' => '3.0.2.0',
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001', 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../psr/log', 'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(), 'aliases' => array(),

View File

@@ -19,8 +19,7 @@ if ($issues) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
} }
} }
trigger_error( throw new \RuntimeException(
'Composer detected issues in your platform: ' . implode(' ', $issues), 'Composer detected issues in your platform: ' . implode(' ', $issues)
E_USER_ERROR
); );
} }

View File

@@ -54,7 +54,8 @@ return [
// Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist. // Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist.
// (See `backward_compatibility_checks` for additional options) // (See `backward_compatibility_checks` for additional options)
// Automatically inferred from composer.json requirement for "php" of ">=8.2" // Automatically inferred from composer.json requirement for "php" of ">=8.2"
'target_php_version' => '8.1', 'target_php_version' => '8.2',
"minimum_target_php_version" => "8.2",
// If enabled, missing properties will be created when // If enabled, missing properties will be created when
// they are first seen. If false, we'll report an // they are first seen. If false, we'll report an
@@ -370,6 +371,7 @@ return [
'file_list' => [ 'file_list' => [
"./test/configs/config.php", "./test/configs/config.php",
"./test/configs/config.other.php", "./test/configs/config.other.php",
"./test/configs/config.path.php",
"./test/configs/config.master.php", "./test/configs/config.master.php",
], ],
]; ];

View File

@@ -3,6 +3,7 @@
"description": "CoreLibs in a composer package", "description": "CoreLibs in a composer package",
"type": "library", "type": "library",
"license": "MIT", "license": "MIT",
"keywords": ["corelib", "logging", "database", "templating", "tools"],
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"CoreLibs\\": "src/" "CoreLibs\\": "src/"
@@ -20,7 +21,11 @@
"psr/log": "^3.0@dev" "psr/log": "^3.0@dev"
}, },
"require-dev": { "require-dev": {
"egrajp/smarty-extended": "^4.3", "phpstan/phpstan": "^2.0",
"phpstan/phpdoc-parser": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phan/phan": "^5.4",
"egrajp/smarty-extended": "^5.4",
"gullevek/dotenv": "dev-master", "gullevek/dotenv": "dev-master",
"phpunit/phpunit": "^9" "phpunit/phpunit": "^9"
}, },

View File

@@ -8,5 +8,6 @@ $_SERVER['HTTP_HOST'] = 'soba.tokyo.tequila.jp';
// for whatever reason it does not load that from the confing.master.php // for whatever reason it does not load that from the confing.master.php
// for includes/admin_header.php // for includes/admin_header.php
define('BASE_NAME', ''); define('BASE_NAME', '');
define('CONTENT_PATH', '');
// __END__ // __END__

View File

@@ -22,6 +22,9 @@ parameters:
# - vendor # - vendor
# ignore errores with # ignore errores with
ignoreErrors: 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 #- # 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\\.$#" # 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 # path: %currentWorkingDirectory%/www/lib/CoreLibs/DB/SQL/PgSQL.php

View File

@@ -4,4 +4,9 @@
verbose="true" verbose="true"
bootstrap="test/phpunit/bootstrap.php" bootstrap="test/phpunit/bootstrap.php"
> >
<testsuites>
<testsuite name="deploy">
<directory>test/phpunit</directory>
</testsuite>
</testsuites>
</phpunit> </phpunit>

View File

@@ -1 +1 @@
9.13.2 9.36.0

View File

@@ -9,16 +9,85 @@ VERSION=$(git tag --list | sort -V | tail -n1 | sed -e "s/^v//");
file_last_published="${BASE_FOLDER}last.published"; file_last_published="${BASE_FOLDER}last.published";
go_flag="$1"; go_flag="$1";
function gitea_publish
{
_GITEA_PUBLISH="${1}"
_GITEA_UPLOAD_FILENAME="${2}"
_GITEA_URL_DL="${3}"
_GITEA_URL_PUSH="${4}"
_GITEA_USER="${5}"
_GITEA_TOKEN="${6}"
_PACKAGE_DOWNLOAD="${7}"
_VERSION="${8}"
_file_last_published="${9}"
if [ -z "${_GITEA_PUBLISH}" ]; then
return
fi;
if [ -n "${_GITEA_UPLOAD_FILENAME}" ] &&
[ -n "${_GITEA_URL_DL}" ] && [ -n "${_GITEA_URL_PUSH}" ] &&
[ -n "${_GITEA_USER}" ] && [ -n "${_GITEA_TOKEN}" ]; then
echo "> Publish ${_GITEA_UPLOAD_FILENAME} with ${_VERSION} to: ${_GITEA_URL_PUSH}";
if [ ! -f "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" ]; then
echo "> Download: ${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip";
curl -LJO \
--output-dir "${_PACKAGE_DOWNLOAD}" \
"${_GITEA_URL_DL}"/v"${_VERSION}".zip;
fi;
if [ ! -f "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" ]; then
echo "[!] Package file does not exist for version: ${_VERSION}";
else
response=$(curl --user "${_GITEA_USER}":"${_GITEA_TOKEN}" \
--upload-file "${_PACKAGE_DOWNLOAD}${_GITEA_UPLOAD_FILENAME}-v${_VERSION}.zip" \
"${_GITEA_URL_PUSH}"?version="${_VERSION}");
status=$(echo "${response}" | jq .errors[].status);
message=$(echo "${response}" | jq .errors[].message);
if [ -n "${status}" ]; then
echo "[!] Error ${status}: ${message}";
else
echo "> Publish completed";
fi;
echo "${_VERSION}" > "${_file_last_published}";
fi;
else
echo "[!] Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
fi;
}
function gitlab_publish
{
_GITLAB_PUBLISH="${1}";
_GITLAB_URL="${2}";
_GITLAB_DEPLOY_TOKEN="${3}";
_PACKAGE_DOWNLOAD="${4}"
_VERSION="${5}"
_file_last_published="${6}"
if [ -z "${GITLAB_PUBLISH}" ]; then
return;
fi;
if [ -n "${_GITLAB_URL}" ] && [ -n "${_GITLAB_DEPLOY_TOKEN}" ]; then
curl --data tag=v"${_VERSION}" \
--header "Deploy-Token: ${_GITLAB_DEPLOY_TOKEN}" \
"${_GITLAB_URL}";
curl --data branch=master \
--header "Deploy-Token: ${_GITLAB_DEPLOY_TOKEN}" \
"${_GITLAB_URL}";
echo "${_VERSION}" > "${_file_last_published}";
else
echo "[!] Missing GITLAB_URL or GITLAB_DEPLOY_TOKEN environment variable";
fi;
}
if [ -z "${VERSION}" ]; then if [ -z "${VERSION}" ]; then
echo "Version must be set in the form x.y.z without any leading characters"; echo "[!] Version must be set in the form x.y.z without any leading characters";
exit; exit;
fi; fi;
# compare version, if different or newer, deploy # compare version, if different or newer, deploy
if [ -f "${file_last_published}" ]; then if [ -f "${file_last_published}" ]; then
LAST_PUBLISHED_VERSION=$(cat "${file_last_published}"); LAST_PUBLISHED_VERSION=$(cat "${file_last_published}");
if dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"; then if dpkg --compare-versions "${VERSION}" le "${LAST_PUBLISHED_VERSION}"; then
echo "git tag version ${VERSION} is not newer than previous published version ${LAST_PUBLISHED_VERSION}"; echo "[!] git tag version ${VERSION} is not newer than previous published version ${LAST_PUBLISHED_VERSION}";
exit;
fi; fi;
fi; fi;
@@ -36,62 +105,30 @@ fi;
# GITLAB_TOKEN # GITLAB_TOKEN
# GITLAB_URL # GITLAB_URL
if [ ! -f "${BASE_FOLDER}.env.deploy" ]; then if [ ! -f "${BASE_FOLDER}.env.deploy" ]; then
echo "Deploy enviroment file .env.deploy is missing"; echo "[!] Deploy enviroment file .env.deploy is missing";
exit; exit;
fi; fi;
set -o allexport; set -o allexport;
cd "${BASE_FOLDER}" || exit; cd "${BASE_FOLDER}" || exit
# shellcheck source=.env.deploy # shellcheck source=.env.deploy
source .env.deploy; source .env.deploy;
cd - || exit; cd - >/dev/null 2>&1 || exit;
set +o allexport; set +o allexport;
if [ "${go_flag}" != "go" ]; then if [ "${go_flag}" != "go" ]; then
echo "No go flag given"; echo "[!] No go flag given";
echo "Would publish ${VERSION}"; echo "> Would publish ${VERSION}";
echo "[END]"; echo "[END]";
exit; exit;
fi; fi;
echo "[START]"; echo "[START]";
# gitea # gitea
# skip iof gitea_publish "${GITEA_PUBLISH}" "${GITEA_UPLOAD_FILENAME}" "${GITEA_URL_DL}" "${GITEA_URL_PUSH}" "${GITEA_USER}" "${GITEA_TOKEN}" "${PACKAGE_DOWNLOAD}" "${VERSION}" "${file_last_published}";
if [ -n "${GITEA_PUBLISH}" ]; then gitea_publish "${PR_GITEA_PUBLISH}" "${PR_GITEA_UPLOAD_FILENAME}" "${PR_GITEA_URL_DL}" "${PR_GITEA_URL_PUSH}" "${PR_GITEA_USER}" "${PR_GITEA_TOKEN}" "${PACKAGE_DOWNLOAD}" "${VERSION}" "${file_last_published}";
if [ -n "${GITEA_UPLOAD_FILENAME}" ] &&
[ -n "${GITEA_URL_DL}" ] && [ -n "${GITEA_URL_PUSH}" ] &&
[ -n "${GITEA_USER}" ] && [ -n "${GITEA_TOKEN}" ]; then
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
curl -LJO \
--output-dir "${PACKAGE_DOWNLOAD}" \
"${GITEA_URL_DL}"/v"${VERSION}".zip;
fi;
if [ ! -f "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" ]; then
echo "Version file does not exist for ${VERSION}";
else
curl --user "${GITEA_USER}":"${GITEA_TOKEN}" \
--upload-file "${PACKAGE_DOWNLOAD}${GITEA_UPLOAD_FILENAME}-v${VERSION}.zip" \
"${GITEA_URL_PUSH}"?version="${VERSION}";
echo "${VERSION}" > "${file_last_published}";
fi;
else
echo "Missing either GITEA_UPLOAD_FILENAME, GITEA_URL_DL, GITEA_URL_PUSH, GITEA_USER or GITEA_TOKEN environment variable";
fi;
fi;
# gitlab # gitlab
if [ -n "${GITLAB_PUBLISH}" ]; then # gitlab_publish "${GITLAB_PUBLISH}" "${GITLAB_URL}" "${GITLAB_DEPLOY_TOKEN}" "${PACKAGE_DOWNLOAD}" "${VERSION}" "${file_last_published}";
if [ -n "${GITLAB_URL}" ] && [ -n "${GITLAB_DEPLOY_TOKEN}" ]; then
curl --data tag=v"${VERSION}" \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
curl --data branch=master \
--header "Deploy-Token: ${GITLAB_DEPLOY_TOKEN}" \
"${GITLAB_URL}";
echo "${VERSION}" > "${file_last_published}";
else
echo "Missing GITLAB_URL or GITLAB_DEPLOY_TOKEN environment variable";
fi;
fi;
echo ""; echo "";
echo "[DONE]"; echo "[DONE]";

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,9 @@ declare(strict_types=1);
namespace CoreLibs\Admin; namespace CoreLibs\Admin;
use CoreLibs\Create\Uids;
use CoreLibs\Convert\Json;
class Backend class Backend
{ {
// page name // page name
@@ -42,7 +45,7 @@ class Backend
/** @var array<string> */ /** @var array<string> */
public array $action_list = [ public array $action_list = [
'action', 'action_id', 'action_sub_id', 'action_yes', 'action_flag', 'action', 'action_id', 'action_sub_id', 'action_yes', 'action_flag',
'action_menu', 'action_value', 'action_error', 'action_loaded' 'action_menu', 'action_value', 'action_type', 'action_error', 'action_loaded'
]; ];
/** @var string */ /** @var string */
public string $action; public string $action;
@@ -61,20 +64,31 @@ class Backend
/** @var string */ /** @var string */
public string $action_value; public string $action_value;
/** @var string */ /** @var string */
public string $action_type;
/** @var string */
public string $action_error; public string $action_error;
// ACL array variable if we want to set acl data from outisde // ACL array variable if we want to set acl data from outisde
/** @var array<mixed> */ /** @var array<mixed> */
public array $acl = []; public array $acl = [];
/** @var int */ /** @var int */
public int $default_acl; public int $default_acl;
// queue key // queue key
/** @var string */ /** @var string */
public string $queue_key; public string $queue_key;
/** @var array<string> list of allowed types for edit log write */
private const WRITE_TYPES = ['BINARY', 'BZIP2', 'LZIP', 'STRING', 'SERIAL', 'JSON'];
/** @var array<string> list of available write types for log */
private array $write_types_available = [];
// the current active edit access id // the current active edit access id
/** @var int|null */ /** @var int|null */
public int|null $edit_access_id; public int|null $edit_access_id;
/** @var string */ /** @var string */
public string $page_name; public string $page_name;
// error/warning/info messages // error/warning/info messages
/** @var array<mixed> */ /** @var array<mixed> */
public array $messages = []; public array $messages = [];
@@ -84,6 +98,7 @@ class Backend
public bool $warning = false; public bool $warning = false;
/** @var bool */ /** @var bool */
public bool $info = false; public bool $info = false;
// internal lang & encoding vars // internal lang & encoding vars
/** @var string */ /** @var string */
public string $lang_dir = ''; public string $lang_dir = '';
@@ -95,6 +110,7 @@ class Backend
public string $domain; public string $domain;
/** @var string */ /** @var string */
public string $encoding; public string $encoding;
/** @var \CoreLibs\Logging\Logging logger */ /** @var \CoreLibs\Logging\Logging logger */
public \CoreLibs\Logging\Logging $log; public \CoreLibs\Logging\Logging $log;
/** @var \CoreLibs\DB\IO database */ /** @var \CoreLibs\DB\IO database */
@@ -103,6 +119,7 @@ class Backend
public \CoreLibs\Language\L10n $l; public \CoreLibs\Language\L10n $l;
/** @var \CoreLibs\Create\Session session class */ /** @var \CoreLibs\Create\Session session class */
public \CoreLibs\Create\Session $session; public \CoreLibs\Create\Session $session;
// smarty publics [end processing in smarty class] // smarty publics [end processing in smarty class]
/** @var array<mixed> */ /** @var array<mixed> */
public array $DATA = []; public array $DATA = [];
@@ -117,18 +134,20 @@ class Backend
/** /**
* main class constructor * main class constructor
* *
* @param \CoreLibs\DB\IO $db Database connection class * @param \CoreLibs\DB\IO $db Database connection class
* @param \CoreLibs\Logging\Logging $log Logging class * @param \CoreLibs\Logging\Logging $log Logging class
* @param \CoreLibs\Create\Session $session Session interface class * @param \CoreLibs\Create\Session $session Session interface class
* @param \CoreLibs\Language\L10n $l10n l10n language class * @param \CoreLibs\Language\L10n $l10n l10n language class
* @param int|null $set_default_acl_level Default ACL level * @param int|null $set_default_acl_level [default=null] Default ACL level
* @param bool $init_action_vars [default=true] If the action vars should be set
*/ */
public function __construct( public function __construct(
\CoreLibs\DB\IO $db, \CoreLibs\DB\IO $db,
\CoreLibs\Logging\Logging $log, \CoreLibs\Logging\Logging $log,
\CoreLibs\Create\Session $session, \CoreLibs\Create\Session $session,
\CoreLibs\Language\L10n $l10n, \CoreLibs\Language\L10n $l10n,
?int $set_default_acl_level = null ?int $set_default_acl_level = null,
bool $init_action_vars = true
) { ) {
// attach db class // attach db class
$this->db = $db; $this->db = $db;
@@ -151,9 +170,9 @@ class Backend
// set the page name // set the page name
$this->page_name = \CoreLibs\Get\System::getPageName(); $this->page_name = \CoreLibs\Get\System::getPageName();
// set the action ids // NOTE: if any of the "action" vars are used somewhere, it is recommended to NOT set them here
foreach ($this->action_list as $_action) { if ($init_action_vars) {
$this->$_action = $_POST[$_action] ?? ''; $this->adbSetActionVars();
} }
if ($set_default_acl_level === null) { if ($set_default_acl_level === null) {
@@ -170,9 +189,12 @@ class Backend
} }
// queue key // queue key
if (preg_match("/^(add|save|delete|remove|move|up|down|push_live)$/", $this->action)) { if (preg_match("/^(add|save|delete|remove|move|up|down|push_live)$/", $this->action ?? '')) {
$this->queue_key = \CoreLibs\Create\RandomKey::randomKeyGen(3); $this->queue_key = \CoreLibs\Create\RandomKey::randomKeyGen(3);
} }
// check what edit log data write types are allowed
$this->adbSetEditLogWriteTypeAvailable();
} }
/** /**
@@ -183,7 +205,26 @@ class Backend
// NO OP // NO OP
} }
// PUBLIC METHODS |=================================================> // MARK: PRIVATE METHODS
/**
* set the write types that are allowed
*
* @return void
*/
private function adbSetEditLogWriteTypeAvailable()
{
// check what edit log data write types are allowed
$this->write_types_available = self::WRITE_TYPES;
if (!function_exists('bzcompress')) {
$this->write_types_available = array_diff($this->write_types_available, ['BINARY', 'BZIP']);
}
if (!function_exists('gzcompress')) {
$this->write_types_available = array_diff($this->write_types_available, ['LZIP']);
}
}
// MARK: PUBLIC METHODS |=================================================>
/** /**
* set internal ACL from login ACL * set internal ACL from login ACL
@@ -195,30 +236,117 @@ class Backend
$this->acl = $acl; $this->acl = $acl;
} }
/**
* Return current set ACL
*
* @return array<mixed>
*/
public function adbGetAcl(): array
{
return $this->acl;
}
/**
* Set _POST action vars if needed
*
* @return void
*/
public function adbSetActionVars()
{
// set the action ids
foreach ($this->action_list as $_action) {
$this->$_action = $_POST[$_action] ?? '';
}
}
/**
* return all the action data, if not set, sets entry to null
*
* @return array{action:?string,action_id:null|string|int,action_sub_id:null|string|int,action_yes:null|string|int|bool,action_flag:?string,action_menu:?string,action_loaded:?string,action_value:?string,action_type:?string,action_error:?string}
*/
public function adbGetActionSet(): array
{
return [
'action' => $this->action ?? null,
'action_id' => $this->action_id ?? null,
'action_sub_id' => $this->action_sub_id ?? null,
'action_yes' => $this->action_yes ?? null,
'action_flag' => $this->action_flag ?? null,
'action_menu' => $this->action_menu ?? null,
'action_loaded' => $this->action_loaded ?? null,
'action_value' => $this->action_value ?? null,
'action_type' => $this->action_type ?? null,
'action_error' => $this->action_error ?? null,
];
}
/** /**
* writes all action vars plus other info into edit_log table * writes all action vars plus other info into edit_log table
* *
* @param string $event any kind of event description, * @param string $event [default=''] any kind of event description,
* @param string|array<mixed> $data any kind of data related to that event * @param string|array<mixed> $data [default=''] any kind of data related to that event
* @param string $write_type write type can bei STRING or BINARY * @param string $write_type [default=JSON] write type can be
* @param string|null $db_schema override target schema * JSON, STRING/SERIEAL, BINARY/BZIP or ZLIB
* @param string|null $db_schema [default=null] override target schema
* @return void * @return void
* @deprecated Use $login->writeLog($event, $data, action_set:$cms->adbGetActionSet(), write_type:$write_type)
*/ */
public function adbEditLog( public function adbEditLog(
string $event = '', string $event = '',
string|array $data = '', string|array $data = '',
string $write_type = 'STRING', string $write_type = 'JSON',
?string $db_schema = null ?string $db_schema = null
): void { ): void {
$data_binary = ''; $data_binary = '';
$data_write = ''; $data_write = '';
if ($write_type == 'BINARY') { // check if write type is valid, if not fallback to JSON
$data_binary = $this->db->dbEscapeBytea((string)bzcompress(serialize($data))); if (!in_array($write_type, $this->write_types_available)) {
$data_write = 'see bzip compressed data_binary field'; $this->log->warning('Write type not in allowed array, fallback to JSON', context:[
"write_type" => $write_type,
"write_list" => $this->write_types_available,
]);
$write_type = 'JSON';
} }
if ($write_type == 'STRING') { switch ($write_type) {
$data_binary = ''; case 'BINARY':
$data_write = $this->db->dbEscapeString(serialize($data)); case 'BZIP':
$data_binary = $this->db->dbEscapeBytea((string)bzcompress(serialize($data)));
$data_write = Json::jsonConvertArrayTo([
'type' => 'BZIP',
'message' => 'see bzip compressed data_binary field'
]);
break;
case 'ZLIB':
$data_binary = $this->db->dbEscapeBytea((string)gzcompress(serialize($data)));
$data_write = Json::jsonConvertArrayTo([
'type' => 'ZLIB',
'message' => 'see zlib compressed data_binary field'
]);
break;
case 'STRING':
case 'SERIAL':
$data_binary = $this->db->dbEscapeBytea(Json::jsonConvertArrayTo([
'type' => 'SERIAL',
'message' => 'see serial string data field'
]));
$data_write = serialize($data);
break;
case 'JSON':
$data_binary = $this->db->dbEscapeBytea(Json::jsonConvertArrayTo([
'type' => 'JSON',
'message' => 'see json string data field'
]));
// must be converted to array
if (!is_array($data)) {
$data = ["data" => $data];
}
$data_write = Json::jsonConvertArrayTo($data);
break;
default:
$this->log->alert('Invalid type for data compression was set', context:[
"write_type" => $write_type
]);
break;
} }
/** @var string $DB_SCHEMA check schema */ /** @var string $DB_SCHEMA check schema */
@@ -228,44 +356,69 @@ class Backend
} elseif (!empty($this->db->dbGetSchema())) { } elseif (!empty($this->db->dbGetSchema())) {
$DB_SCHEMA = $this->db->dbGetSchema(); $DB_SCHEMA = $this->db->dbGetSchema();
} }
$q = "INSERT INTO " . $DB_SCHEMA . ".edit_log " $q = <<<SQL
. "(euid, event_date, event, data, data_binary, page, " INSERT INTO {DB_SCHEMA}.edit_log (
. "ip, user_agent, referer, script_name, query_string, server_name, http_host, " username, euid, eucuid, eucuuid, event_date, event, error, data, data_binary, page,
. "http_accept, http_accept_charset, http_accept_encoding, session_id, " ip, user_agent, referer, script_name, query_string, server_name, http_host,
. "action, action_id, action_yes, action_flag, action_menu, action_loaded, action_value, action_error) " http_accept, http_accept_charset, http_accept_encoding, session_id,
. "VALUES " action, action_id, action_sub_id, action_yes, action_flag, action_menu, action_loaded,
. "(" . $this->db->dbEscapeString(isset($_SESSION['EUID']) && is_numeric($_SESSION['EUID']) ? action_value, action_type, action_error
$_SESSION['EUID'] : ) VALUES (
'NULL') $1, $2, $3, $4, NOW(), $5, $6, $7, $8, $9,
. ", " $10, $11, $12, $13, $14, $15, $16,
. "NOW(), " $17, $18, $19, $20,
. "'" . $this->db->dbEscapeString((string)$event) . "', " $21, $22, $23, $24, $25, $26, $27,
. "'" . $data_write . "', " $28, $29, $30
. "'" . $data_binary . "', " )
. "'" . $this->db->dbEscapeString((string)$this->page_name) . "', " SQL;
. "'" . ($_SERVER["REMOTE_ADDR"] ?? '') . "', " $this->db->dbExecParams(
. "'" . $this->db->dbEscapeString($_SERVER['HTTP_USER_AGENT'] ?? '') . "', " str_replace(
. "'" . $this->db->dbEscapeString($_SERVER['HTTP_REFERER'] ?? '') . "', " ['{DB_SCHEMA}'],
. "'" . $this->db->dbEscapeString($_SERVER['SCRIPT_FILENAME'] ?? '') . "', " [$DB_SCHEMA],
. "'" . $this->db->dbEscapeString($_SERVER['QUERY_STRING'] ?? '') . "', " $q
. "'" . $this->db->dbEscapeString($_SERVER['SERVER_NAME'] ?? '') . "', " ),
. "'" . $this->db->dbEscapeString($_SERVER['HTTP_HOST'] ?? '') . "', " [
. "'" . $this->db->dbEscapeString($_SERVER['HTTP_ACCEPT'] ?? '') . "', " // row 1
. "'" . $this->db->dbEscapeString($_SERVER['HTTP_ACCEPT_CHARSET'] ?? '') . "', " '',
. "'" . $this->db->dbEscapeString($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '') . "', " is_numeric($this->session->get('EUID')) ?
. ($this->session->getSessionId() === false ? $this->session->get('EUID') : null,
"NULL" : is_string($this->session->get('ECUID')) ?
"'" . $this->session->getSessionId() . "'") $this->session->get('ECUID') : null,
. ", " !empty($this->session->get('ECUUID')) && Uids::validateUuuidv4($this->session->get('ECUID')) ?
. "'" . $this->db->dbEscapeString($this->action) . "', " $this->session->get('ECUID') : null,
. "'" . $this->db->dbEscapeString($this->action_id) . "', " (string)$event,
. "'" . $this->db->dbEscapeString($this->action_yes) . "', " '',
. "'" . $this->db->dbEscapeString($this->action_flag) . "', " $data_write,
. "'" . $this->db->dbEscapeString($this->action_menu) . "', " $data_binary,
. "'" . $this->db->dbEscapeString($this->action_loaded) . "', " (string)$this->page_name,
. "'" . $this->db->dbEscapeString($this->action_value) . "', " // row 2
. "'" . $this->db->dbEscapeString($this->action_error) . "')"; $_SERVER["REMOTE_ADDR"] ?? '',
$this->db->dbExec($q, 'NULL'); $_SERVER['HTTP_USER_AGENT'] ?? '',
$_SERVER['HTTP_REFERER'] ?? '',
$_SERVER['SCRIPT_FILENAME'] ?? '',
$_SERVER['QUERY_STRING'] ?? '',
$_SERVER['SERVER_NAME'] ?? '',
$_SERVER['HTTP_HOST'] ?? '',
// row 3
$_SERVER['HTTP_ACCEPT'] ?? '',
$_SERVER['HTTP_ACCEPT_CHARSET'] ?? '',
$_SERVER['HTTP_ACCEPT_ENCODING'] ?? '',
$this->session->getSessionId() !== '' ?
$this->session->getSessionId() : null,
// row 4
$this->action ?? '',
$this->action_id ?? '',
$this->action_sub_id ?? '',
$this->action_yes ?? '',
$this->action_flag ?? '',
$this->action_menu ?? '',
$this->action_loaded ?? '',
$this->action_value ?? '',
$this->action_type ?? '',
$this->action_error ?? '',
],
'NULL'
);
} }
/** /**
@@ -302,10 +455,7 @@ class Backend
?string $set_content_path = null, ?string $set_content_path = null,
int $flag = 0, int $flag = 0,
): array { ): array {
if ( if ($set_content_path === null) {
$set_content_path === null ||
!is_string($set_content_path)
) {
/** @deprecated adbTopMenu missing set_content_path parameter */ /** @deprecated adbTopMenu missing set_content_path parameter */
trigger_error( trigger_error(
'Calling adbTopMenu without set_content_path parameter is deprecated', 'Calling adbTopMenu without set_content_path parameter is deprecated',
@@ -318,7 +468,7 @@ class Backend
} }
// get the session pages array // get the session pages array
$PAGES = $_SESSION['PAGES'] ?? null; $PAGES = $this->session->get('PAGES');
if (!isset($PAGES) || !is_array($PAGES)) { if (!isset($PAGES) || !is_array($PAGES)) {
$PAGES = []; $PAGES = [];
} }
@@ -504,9 +654,9 @@ class Backend
string $data, string $data,
string $key_name, string $key_name,
string $key_value, string $key_value,
string $associate = null, ?string $associate = null,
string $file = null, ?string $file = null,
string $db_schema = null, ?string $db_schema = null,
): void { ): void {
/** @var string $DB_SCHEMA check schema */ /** @var string $DB_SCHEMA check schema */
$DB_SCHEMA = 'public'; $DB_SCHEMA = 'public';
@@ -515,16 +665,30 @@ class Backend
} elseif (!empty($this->db->dbGetSchema())) { } elseif (!empty($this->db->dbGetSchema())) {
$DB_SCHEMA = $this->db->dbGetSchema(); $DB_SCHEMA = $this->db->dbGetSchema();
} }
$q = "INSERT INTO " . $DB_SCHEMA . ".live_queue (" $q = <<<SQL
. "queue_key, key_value, key_name, type, target, data, group_key, action, associate, file" INSERT INTO {DB_SCHEMA}.live_queue (
. ") VALUES (" queue_key, key_value, key_name, type,
. "'" . $this->db->dbEscapeString($queue_key) . "', '" . $this->db->dbEscapeString($key_value) . "', " target, data, group_key, action, associate, file
. "'" . $this->db->dbEscapeString($key_name) . "', '" . $this->db->dbEscapeString($type) . "', " ) VALUES (
. "'" . $this->db->dbEscapeString($target) . "', '" . $this->db->dbEscapeString($data) . "', " $1, $2, $3, $4,
. "'" . $this->queue_key . "', '" . $this->action . "', " $5, $6, $7, $8, $9, $10
. "'" . $this->db->dbEscapeString((string)$associate) . "', " )
. "'" . $this->db->dbEscapeString((string)$file) . "')"; SQL;
$this->db->dbExec($q); // $this->db->dbExec($q);
$this->db->dbExecParams(
str_replace(
['{DB_SCHEMA}'],
[$DB_SCHEMA],
$q
),
[
$queue_key, $key_value,
$key_name, $type,
$target, $data,
$this->queue_key, $this->action,
(string)$associate, (string)$file
]
);
} }
/** /**

View File

@@ -14,9 +14,6 @@ declare(strict_types=1);
namespace CoreLibs\Admin; namespace CoreLibs\Admin;
use Exception;
use SmartyException;
class EditBase class EditBase
{ {
/** @var array<mixed> */ /** @var array<mixed> */
@@ -63,6 +60,7 @@ class EditBase
// smarty template engine (extended Translation version) // smarty template engine (extended Translation version)
$this->smarty = new \CoreLibs\Template\SmartyExtend( $this->smarty = new \CoreLibs\Template\SmartyExtend(
$l10n, $l10n,
$log,
$options['cache_id'] ?? '', $options['cache_id'] ?? '',
$options['compile_id'] ?? '', $options['compile_id'] ?? '',
); );
@@ -78,7 +76,7 @@ class EditBase
); );
if ($this->form->mobile_phone) { if ($this->form->mobile_phone) {
echo "I am sorry, but this page cannot be viewed by a 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)); // $this->log->debug('POST', $this->log->prAr($_POST));
} }
@@ -415,8 +413,6 @@ class EditBase
$elements[] = $this->form->formCreateElement('lock_until'); $elements[] = $this->form->formCreateElement('lock_until');
$elements[] = $this->form->formCreateElement('lock_after'); $elements[] = $this->form->formCreateElement('lock_after');
$elements[] = $this->form->formCreateElement('admin'); $elements[] = $this->form->formCreateElement('admin');
$elements[] = $this->form->formCreateElement('debug');
$elements[] = $this->form->formCreateElement('db_debug');
$elements[] = $this->form->formCreateElement('edit_language_id'); $elements[] = $this->form->formCreateElement('edit_language_id');
$elements[] = $this->form->formCreateElement('edit_scheme_id'); $elements[] = $this->form->formCreateElement('edit_scheme_id');
$elements[] = $this->form->formCreateElementListTable('edit_access_user'); $elements[] = $this->form->formCreateElementListTable('edit_access_user');
@@ -540,8 +536,7 @@ class EditBase
* builds the smarty content and runs smarty display output * builds the smarty content and runs smarty display output
* *
* @return void * @return void
* @throws Exception * @throws \Smarty\Exception
* @throws SmartyException
*/ */
public function editBaseRun( public function editBaseRun(
?string $template_dir = null, ?string $template_dir = null,

View File

@@ -90,7 +90,7 @@ class Basic
* @deprecated DO NOT USE Class\Basic anymore. Use dedicated logger and sub classes * @deprecated DO NOT USE Class\Basic anymore. Use dedicated logger and sub classes
*/ */
public function __construct( public function __construct(
\CoreLibs\Logging\Logging $log = null, ?\CoreLibs\Logging\Logging $log = null,
?string $session_name = null ?string $session_name = null
) { ) {
trigger_error('Class \CoreLibs\Basic is deprected', E_USER_DEPRECATED); trigger_error('Class \CoreLibs\Basic is deprected', E_USER_DEPRECATED);
@@ -103,11 +103,7 @@ class Basic
'VIDEOS', 'DOCUMENTS', 'PDFS', 'BINARIES', 'ICONS', 'UPLOADS', 'CSV', 'JS', 'VIDEOS', 'DOCUMENTS', 'PDFS', 'BINARIES', 'ICONS', 'UPLOADS', 'CSV', 'JS',
'CSS', 'TABLE_ARRAYS', 'SMARTY', 'LANG', 'CACHE', 'TMP', 'LOG', 'TEMPLATES', 'CSS', 'TABLE_ARRAYS', 'SMARTY', 'LANG', 'CACHE', 'TMP', 'LOG', 'TEMPLATES',
'TEMPLATES_C', 'DEFAULT_LANG', 'DEFAULT_ENCODING', 'DEFAULT_HASH', 'TEMPLATES_C', 'DEFAULT_LANG', 'DEFAULT_ENCODING', 'DEFAULT_HASH',
'DEFAULT_ACL_LEVEL', 'LOGOUT_TARGET', 'PASSWORD_CHANGE', 'AJAX_REQUEST_TYPE', 'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET'
'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'
] as $constant ] as $constant
) { ) {
if (!defined($constant)) { if (!defined($constant)) {
@@ -387,7 +383,8 @@ class Basic
public function initRandomKeyLength(int $key_length): bool public function initRandomKeyLength(int $key_length): bool
{ {
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\RandomKey::setRandomKeyLength()', E_USER_DEPRECATED); trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\RandomKey::setRandomKeyLength()', E_USER_DEPRECATED);
return \CoreLibs\Create\RandomKey::setRandomKeyLength($key_length); // no op, we do no longer pre set the random key length
return true;
} }
/** /**
@@ -992,10 +989,10 @@ class Basic
* @param bool $auto_check default true, if source encoding is set * @param bool $auto_check default true, if source encoding is set
* check that the source is actually matching * check that the source is actually matching
* to what we sav the source is * to what we sav the source is
* @return string encoding converted string * @return string|false encoding converted string
* @deprecated use \CoreLibs\Convert\Encoding::convertEncoding() instead * @deprecated use \CoreLibs\Convert\Encoding::convertEncoding() instead
*/ */
public static function convertEncoding(string $string, string $to_encoding, string $source_encoding = '', bool $auto_check = true): string public static function convertEncoding(string $string, string $to_encoding, string $source_encoding = '', bool $auto_check = true): string|false
{ {
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Encoding::convertEncoding()', E_USER_DEPRECATED); trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Encoding::convertEncoding()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Encoding::convertEncoding($string, $to_encoding, $source_encoding, $auto_check); return \CoreLibs\Convert\Encoding::convertEncoding($string, $to_encoding, $source_encoding, $auto_check);
@@ -1028,8 +1025,12 @@ class Basic
*/ */
public function __sha1Short(string $string, bool $use_sha = false): string public function __sha1Short(string $string, bool $use_sha = false): string
{ {
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::__sha1Short()', E_USER_DEPRECATED); trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::sha1Short() or ::__crc32b()', E_USER_DEPRECATED);
return \CoreLibs\Create\Hash::__sha1Short($string, $use_sha); if ($use_sha) {
return \CoreLibs\Create\Hash::sha1Short($string);
} else {
return \CoreLibs\Create\Hash::__crc32b($string);
}
} }
/** /**
@@ -1044,8 +1045,8 @@ class Basic
*/ */
public function __hash(string $string, string $hash_type = 'adler32'): string public function __hash(string $string, string $hash_type = 'adler32'): string
{ {
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::__hash()', E_USER_DEPRECATED); trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Create\Hash::hash()', E_USER_DEPRECATED);
return \CoreLibs\Create\Hash::__hash($string, $hash_type); return \CoreLibs\Create\Hash::hash($string, $hash_type);
} }
// *** HASH FUNCTIONS END // *** HASH FUNCTIONS END
@@ -1139,118 +1140,6 @@ class Basic
// *** BETTER PASSWORD OPTIONS END *** // *** BETTER PASSWORD OPTIONS END ***
// *** COLORS ***
// [!!! DEPRECATED !!!]
// moved to \CoreLibs\Convert\Colors
/**
* converts a hex RGB color to the int numbers
* @param string $hexStr RGB hexstring
* @param bool $returnAsString flag to return as string
* @param string $seperator string seperator: default: ","
* @return string|array<mixed>|bool false on error or array with RGB or
* a string with the seperator
* @deprecated use \CoreLibs\Convert\Colors::hex2rgb() instead
*/
public static function hex2rgb(string $hexStr, bool $returnAsString = false, string $seperator = ',')
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::hex2rgb()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Colors::hex2rgb($hexStr, $returnAsString, $seperator);
}
/**
* converts the rgb values from int data to the valid rgb html hex string
* optional can turn of leading #
* @param int $red red 0-255
* @param int $green green 0-255
* @param int $blue blue 0-255
* @param bool $hex_prefix default true, prefix with "#"
* @return string|bool rgb in hex values with leading # if set
* @deprecated use \CoreLibs\Convert\Colors::rgb2hex() instead
*/
public static function rgb2hex(int $red, int $green, int $blue, bool $hex_prefix = true)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::rgb2hex()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Colors::rgb2hex($red, $green, $blue, $hex_prefix);
}
/**
* converts and int RGB to the HTML color string in hex format
* @param int $red red 0-255
* @param int $green green 0-255
* @param int $blue blue 0-255
* @return string|bool hex rgb string
* @deprecated use rgb2hex instead
*/
public static function rgb2html(int $red, int $green, int $blue)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::rgb2hex()', E_USER_DEPRECATED);
// check that each color is between 0 and 255
return \CoreLibs\Convert\Colors::rgb2hex($red, $green, $blue, true);
}
/**
* converts RGB to HSB/V values
* returns:
* array with hue (0-360), sat (0-100%), brightness/value (0-100%)
* @param int $red red 0-255
* @param int $green green 0-255
* @param int $blue blue 0-255
* @return array<mixed>|bool Hue, Sat, Brightness/Value
* @deprecated use \CoreLibs\Convert\Colors::rgb2hsb() instead
*/
public static function rgb2hsb(int $red, int $green, int $blue)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::rgb2hsb()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Colors::rgb2hsb($red, $green, $blue);
}
/**
* converts HSB/V to RGB values RGB is full INT
* @param int $H hue 0-360
* @param float $S saturation 0-1 (float)
* @param float $V brightness/value 0-1 (float)
* @return array<mixed>|bool 0 red/1 green/2 blue array
* @deprecated use \CoreLibs\Convert\Colors::hsb2rgb() instead
*/
public static function hsb2rgb(int $H, float $S, float $V)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::hsb2rgb()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Colors::hsb2rgb($H, (int)round($S * 100), (int)round($V * 100));
}
/**
* converts a RGB (0-255) to HSL
* return:
* array with hue (0-360), saturation (0-100%) and luminance (0-100%)
* @param int $r red 0-255
* @param int $g green 0-255
* @param int $b blue 0-255
* @return array<mixed>|bool hue/sat/luminance
* @deprecated use \CoreLibs\Convert\Colors::rgb2hsl() instead
*/
public static function rgb2hsl(int $r, int $g, int $b)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::rgb2hsl()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Colors::rgb2hsb($r, $g, $b);
}
/**
* converts an HSL to RGB
* @param int $h hue: 0-360 (degrees)
* @param float $s saturation: 0-1
* @param float $l luminance: 0-1
* @return array<mixed>|bool red/blue/green 0-255 each
* @deprecated use \CoreLibs\Convert\Colors::hsl2rgb() instead
*/
public static function hsl2rgb(int $h, float $s, float $l)
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Convert\Colors::hsl2rgb()', E_USER_DEPRECATED);
return \CoreLibs\Convert\Colors::hsl2rgb($h, $s * 100, $l * 100);
}
// *** COLORS END ***
// *** EMAIL FUNCTIONS *** // *** EMAIL FUNCTIONS ***
// [!!! DEPRECATED !!!] // [!!! DEPRECATED !!!]
// Moved to \CoreLibs\Check\Email // Moved to \CoreLibs\Check\Email

View File

@@ -119,6 +119,13 @@ class Colors
/** /**
* check if html/css color string is valid * check if html/css color string is valid
*
* TODO: update check for correct validate values
* - space instead of ","
* - / opcatiy checks
* - loose numeric values
* - lab/lch,oklab/oklch validation too
*
* @param string $color A color string of any format * @param string $color A color string of any format
* @param int $flags defaults to ALL, else use | to combined from * @param int $flags defaults to ALL, else use | to combined from
* HEX_RGB, HEX_RGBA, RGB, RGBA, HSL, HSLA * HEX_RGB, HEX_RGBA, RGB, RGBA, HSL, HSLA
@@ -168,9 +175,9 @@ class Colors
if (preg_match("/$regex/", $color)) { if (preg_match("/$regex/", $color)) {
// if valid regex, we now need to check if the content is actually valid // if valid regex, we now need to check if the content is actually valid
// only for rgb/hsl type // only for rgb/hsl type
/** @var int|false */ /** @var int<0, max>|false */
$rgb_flag = strpos($color, 'rgb'); $rgb_flag = strpos($color, 'rgb');
/** @var int|false */ /** @var int<0, max>|false */
$hsl_flag = strpos($color, 'hsl'); $hsl_flag = strpos($color, 'hsl');
// if both not match, return true // if both not match, return true
if ( if (

View File

@@ -10,12 +10,16 @@ class Email
/** @var array<int,string> */ /** @var array<int,string> */
private static array $email_regex_check = [ private static array $email_regex_check = [
0 => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@" 0 => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$", // MASTER // . "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$", // MASTER
// fixed pattern matching for domain
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$", // MASTER
1 => "@(.*)@(.*)", // double @ 1 => "@(.*)@(.*)", // double @
2 => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@", // wrong part before @ 2 => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@", // wrong part before @
3 => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$", // wrong part after @ // 3 => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$", // wrong part after @
4 => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.", // wrong domain name part 3 => "@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$", // wrong part after @
5 => "\.([a-zA-Z]{2,6}){1}$", // wrong top level part // 4 => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.", // wrong domain name part
4 => "@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.", // wrong domain name part
5 => "\.[a-zA-Z]{2,6}$", // wrong top level part
6 => "@(.*)\.{2,}", // double .. in domain name part 6 => "@(.*)\.{2,}", // double .. in domain name part
7 => "@.*\.$" // ends with a dot, top level, domain missing 7 => "@.*\.$" // ends with a dot, top level, domain missing
]; ];

View File

@@ -56,7 +56,11 @@ class Encoding
{ {
// return mb_substitute_character(); // return mb_substitute_character();
if ($return_substitute_func === true) { if ($return_substitute_func === true) {
return mb_substitute_character(); // if false abort with error
if (($return = mb_substitute_character()) === false) {
return self::$mb_error_char;
}
return $return;
} else { } else {
return self::$mb_error_char; return self::$mb_error_char;
} }
@@ -88,7 +92,13 @@ class Encoding
): array|false { ): array|false {
// convert to target encoding and convert back // convert to target encoding and convert back
$temp = mb_convert_encoding($string, $to_encoding, $from_encoding); $temp = mb_convert_encoding($string, $to_encoding, $from_encoding);
if ($temp === false) {
return false;
}
$compare = mb_convert_encoding($temp, $from_encoding, $to_encoding); $compare = mb_convert_encoding($temp, $from_encoding, $to_encoding);
if ($compare === false) {
return false;
}
// if string does not match anymore we have a convert problem // if string does not match anymore we have a convert problem
if ($string == $compare) { if ($string == $compare) {
return false; return false;
@@ -104,7 +114,7 @@ class Encoding
(($char != $r_char && (!self::$mb_error_char || (($char != $r_char && (!self::$mb_error_char ||
in_array(self::$mb_error_char, ['none', 'long', 'entity']))) || in_array(self::$mb_error_char, ['none', 'long', 'entity']))) ||
($char != $r_char && $r_char == self::$mb_error_char && self::$mb_error_char)) && ($char != $r_char && $r_char == self::$mb_error_char && self::$mb_error_char)) &&
ord($char) != 194 ord($char[0]) != 194
) { ) {
$failed[] = $char; $failed[] = $char;
} }

View File

@@ -10,6 +10,8 @@ namespace CoreLibs\Combined;
class ArrayHandler class ArrayHandler
{ {
public const string DATA_SEPARATOR = ':';
/** /**
* searches key = value in an array / array * searches key = value in an array / array
* only returns the first one found * only returns the first one found
@@ -148,28 +150,32 @@ class ArrayHandler
* array search simple. looks for key, value combination, if found, returns true * array search simple. looks for key, value combination, if found, returns true
* on default does not strict check, so string '4' will match int 4 and vica versa * on default does not strict check, so string '4' will match int 4 and vica versa
* *
* @param array<mixed> $array search in as array * @param array<mixed> $in_array search in as array
* @param string|int $key key (key to search in) * @param string|int $key key (key to search in)
* @param string|int|bool $value value (what to find) * @param string|int|bool|array<string|int|bool> $value values list (what to find)
* @param bool $strict [false], if set to true, will strict check key/value * @param bool $strict [false], if set to true, will strict check key/value
* @return bool true on found, false on not found * @return bool true on found, false on not found
*/ */
public static function arraySearchSimple( public static function arraySearchSimple(
array $array, array $in_array,
string|int $key, string|int $key,
string|int|bool $value, string|int|bool|array $value,
bool $strict = false bool $strict = false
): bool { ): bool {
foreach ($array as $_key => $_value) { // convert to array
if (!is_array($value)) {
$value = [$value];
}
foreach ($in_array as $_key => $_value) {
// if value is an array, we search // if value is an array, we search
if (is_array($_value)) { if (is_array($_value)) {
// call recursive, and return result if it is true, else continue // call recursive, and return result if it is true, else continue
if (($result = self::arraySearchSimple($_value, $key, $value, $strict)) !== false) { if (($result = self::arraySearchSimple($_value, $key, $value, $strict)) !== false) {
return $result; return $result;
} }
} elseif ($strict === false && $_key == $key && $_value == $value) { } elseif ($strict === false && $_key == $key && in_array($_value, $value)) {
return true; return true;
} elseif ($strict === true && $_key === $key && $_value === $value) { } elseif ($strict === true && $_key === $key && in_array($_value, $value, true)) {
return true; return true;
} }
} }
@@ -183,19 +189,19 @@ class ArrayHandler
* If prefix is turned on each found group will be prefixed with the * If prefix is turned on each found group will be prefixed with the
* search key * search key
* *
* @param array<mixed> $array array to search in * @param array<mixed> $in_array array to search in
* @param array<mixed> $needles keys to find in array * @param array<mixed> $needles keys to find in array
* @param bool $flat [false] Turn on flat output * @param bool $flat [false] Turn on flat output
* @param bool $prefix [false] Prefix found with needle key * @param bool $prefix [false] Prefix found with needle key
* @return array<mixed> Found values * @return array<mixed> Found values
*/ */
public static function arraySearchKey( public static function arraySearchKey(
array $array, array $in_array,
array $needles, array $needles,
bool $flat = false, bool $flat = false,
bool $prefix = false bool $prefix = false
): array { ): array {
$iterator = new \RecursiveArrayIterator($array); $iterator = new \RecursiveArrayIterator($in_array);
$recursive = new \RecursiveIteratorIterator( $recursive = new \RecursiveIteratorIterator(
$iterator, $iterator,
\RecursiveIteratorIterator::SELF_FIRST \RecursiveIteratorIterator::SELF_FIRST
@@ -236,17 +242,171 @@ class ArrayHandler
return $hit_list; return $hit_list;
} }
/**
* Search in an array for value with or without key and
* check in the same array block for the required key
* If not found return an array with the array block there the required key is missing,
* the path as string with seperator block set and the missing key entry
*
* @param array<mixed> $in_array
* @param string|int|float|bool $search_value
* @param string|array<string> $required_key
* @param ?string $search_key [null]
* @param string $path_separator [DATA_SEPARATOR]
* @param string $current_path
* @return array<array{content?:array<mixed>,path?:string,missing_key?:array<string>}>
*/
public static function findArraysMissingKey(
array $in_array,
string|int|float|bool $search_value,
string|array $required_key,
?string $search_key = null,
string $path_separator = self::DATA_SEPARATOR,
string $current_path = ''
): array {
$results = [];
foreach ($in_array as $key => $value) {
$path = $current_path ? $current_path . $path_separator . $key : $key;
if (is_array($value)) {
// Check if this array contains the search value
// either any value match or with key
if ($search_key === null) {
$containsValue = in_array($search_value, $value, true);
} else {
$containsValue = array_key_exists($search_key, $value) && $value[$search_key] === $search_value;
}
// If it contains the value but doesn't have the required key
if (
$containsValue &&
(
(
is_string($required_key) &&
!array_key_exists($required_key, $value)
) || (
is_array($required_key) &&
count(array_intersect($required_key, array_keys($value))) !== count($required_key)
)
)
) {
$results[] = [
'content' => $value,
'path' => $path,
'missing_key' => is_array($required_key) ?
array_values(array_diff($required_key, array_keys($value))) :
[$required_key]
];
}
// Recursively search nested arrays
$results = array_merge(
$results,
self::findArraysMissingKey(
$value,
$search_value,
$required_key,
$search_key,
$path_separator,
$path
)
);
}
}
return $results;
}
/**
* Find key => value entry and return set with key for all matching
* Can search recursively through nested arrays if recursive flag is set
*
* @param array<mixed> $in_array
* @param string $lookup
* @param int|string|float|bool $search
* @param bool $strict [false]
* @param bool $case_insensitive [false]
* @param bool $recursive [false]
* @param bool $flat_result [true] If set to false and recursive is on the result is a nested array
* @param string $flat_separator [DATA_SEPARATOR] if flat result is true, can be any string
* @return array<mixed>
*/
public static function selectArrayFromOption(
array $in_array,
string $lookup,
int|string|float|bool $search,
bool $strict = false,
bool $case_insensitive = false,
bool $recursive = false,
bool $flat_result = true,
string $flat_separator = self::DATA_SEPARATOR
): array {
// skip on empty
if ($in_array == []) {
return [];
}
// init return result
$result = [];
// case sensitive convert if string
if ($case_insensitive && is_string($search)) {
$search = strtolower($search);
}
foreach ($in_array as $key => $value) {
// Handle current level search
if (isset($value[$lookup])) {
$compareValue = $value[$lookup];
if ($case_insensitive && is_string($compareValue)) {
$compareValue = strtolower($compareValue);
}
if (
($strict && $search === $compareValue) ||
(!$strict && $search == $compareValue)
) {
$result[$key] = $value;
}
}
// Handle recursive search if flag is set
if ($recursive && is_array($value)) {
$recursiveResults = self::selectArrayFromOption(
$value,
$lookup,
$search,
$strict,
$case_insensitive,
true,
$flat_result,
$flat_separator
);
// Merge recursive results with current results
// Preserve keys by using array_merge with string keys or + operator
foreach ($recursiveResults as $recKey => $recValue) {
if ($flat_result) {
$result[$key . $flat_separator . $recKey] = $recValue;
} else {
$result[$key][$recKey] = $recValue;
}
}
}
}
return $result;
}
/** /**
* main wrapper function for next/prev key * main wrapper function for next/prev key
* *
* @param array<mixed> $array array to search in * @param array<mixed> $in_array array to search in
* @param int|string $key key for next/prev * @param int|string $key key for next/prev
* @param bool $next [=true] if to search next or prev * @param bool $next [=true] if to search next or prev
* @return int|string|null Next/prev key or null for end/first * @return int|string|null Next/prev key or null for end/first
*/ */
private static function arrayGetKey(array $array, int|string $key, bool $next = true): int|string|null private static function arrayGetKey(array $in_array, int|string $key, bool $next = true): int|string|null
{ {
$keys = array_keys($array); $keys = array_keys($in_array);
if (($position = array_search($key, $keys, true)) === false) { if (($position = array_search($key, $keys, true)) === false) {
return null; return null;
} }
@@ -262,26 +422,26 @@ class ArrayHandler
* Get previous array key from an array * Get previous array key from an array
* null on not found * null on not found
* *
* @param array<mixed> $array * @param array<mixed> $in_array
* @param int|string $key * @param int|string $key
* @return int|string|null Next key, or null for not found * @return int|string|null Next key, or null for not found
*/ */
public static function arrayGetPrevKey(array $array, int|string $key): int|string|null public static function arrayGetPrevKey(array $in_array, int|string $key): int|string|null
{ {
return self::arrayGetKey($array, $key, false); return self::arrayGetKey($in_array, $key, false);
} }
/** /**
* Get next array key from an array * Get next array key from an array
* null on not found * null on not found
* *
* @param array<mixed> $array * @param array<mixed> $in_array
* @param int|string $key * @param int|string $key
* @return int|string|null Next key, or null for not found * @return int|string|null Next key, or null for not found
*/ */
public static function arrayGetNextKey(array $array, int|string $key): int|string|null public static function arrayGetNextKey(array $in_array, int|string $key): int|string|null
{ {
return self::arrayGetKey($array, $key, true); return self::arrayGetKey($in_array, $key, true);
} }
/** /**
@@ -303,27 +463,27 @@ class ArrayHandler
} }
// default key is not string // default key is not string
$key_is_string = false; $key_is_string = false;
$arrays = func_get_args(); $in_arrays = func_get_args();
// if last is not array, then assume it is trigger for key is always string // if last is not array, then assume it is trigger for key is always string
if (!is_array(end($arrays))) { if (!is_array(end($in_arrays))) {
if (array_pop($arrays)) { if (array_pop($in_arrays)) {
$key_is_string = true; $key_is_string = true;
} }
} }
// check that arrays count is at least two, else we don't have enough to do anything // check that arrays count is at least two, else we don't have enough to do anything
if (count($arrays) < 2) { if (count($in_arrays) < 2) {
throw new \ArgumentCountError(__FUNCTION__ . ' needs two or more array arguments'); throw new \ArgumentCountError(__FUNCTION__ . ' needs two or more array arguments');
} }
$merged = []; $merged = [];
while ($arrays) { while ($in_arrays) {
$array = array_shift($arrays); $in_array = array_shift($in_arrays);
if (!is_array($array)) { if (!is_array($in_array)) {
throw new \TypeError(__FUNCTION__ . ' encountered a non array argument'); throw new \TypeError(__FUNCTION__ . ' encountered a non array argument');
} }
if (!$array) { if (!$in_array) {
continue; continue;
} }
foreach ($array as $key => $value) { foreach ($in_array as $key => $value) {
// if string or if key is assumed to be string do key match // if string or if key is assumed to be string do key match
// else add new entry // else add new entry
if (is_string($key) || $key_is_string === false) { if (is_string($key) || $key_is_string === false) {
@@ -429,14 +589,14 @@ class ArrayHandler
* converts multi dimensional array to a flat array * converts multi dimensional array to a flat array
* does NOT preserve keys * does NOT preserve keys
* *
* @param array<mixed> $array multi dimensionial array * @param array<mixed> $in_array multi dimensionial array
* @return array<mixed> flattened array * @return array<mixed> flattened array
*/ */
public static function flattenArray(array $array): array public static function flattenArray(array $in_array): array
{ {
$return = []; $return = [];
array_walk_recursive( array_walk_recursive(
$array, $in_array,
function ($value) use (&$return) { function ($value) use (&$return) {
$return[] = $value; $return[] = $value;
} }
@@ -447,13 +607,13 @@ class ArrayHandler
/** /**
* will loop through an array recursivly and write the array keys back * will loop through an array recursivly and write the array keys back
* *
* @param array<mixed> $array multidemnsional array to flatten * @param array<mixed> $in_array multidemnsional array to flatten
* @param array<mixed> $return recoursive pass on array of keys * @param array<mixed> $return recoursive pass on array of keys
* @return array<mixed> flattened keys array * @return array<mixed> flattened keys array
*/ */
public static function flattenArrayKey(array $array, array $return = []): array public static function flattenArrayKey(array $in_array, array $return = []): array
{ {
foreach ($array as $key => $sub) { foreach ($in_array as $key => $sub) {
$return[] = $key; $return[] = $key;
if (is_array($sub) && count($sub) > 0) { if (is_array($sub) && count($sub) > 0) {
$return = self::flattenArrayKey($sub, $return); $return = self::flattenArrayKey($sub, $return);
@@ -466,14 +626,14 @@ class ArrayHandler
* as above will flatten an array, but in this case only the outmost * as above will flatten an array, but in this case only the outmost
* leave nodes, all other keyswill be skipped * leave nodes, all other keyswill be skipped
* *
* @param array<mixed> $array multidemnsional array to flatten * @param array<mixed> $in_array multidemnsional array to flatten
* @return array<mixed> flattened keys array * @return array<mixed> flattened keys array
*/ */
public static function flattenArrayKeyLeavesOnly(array $array): array public static function flattenArrayKeyLeavesOnly(array $in_array): array
{ {
$return = []; $return = [];
array_walk_recursive( array_walk_recursive(
$array, $in_array,
function ($value, $key) use (&$return) { function ($value, $key) use (&$return) {
$return[] = $key; $return[] = $key;
} }
@@ -485,14 +645,14 @@ class ArrayHandler
* searches for key -> value in an array tree and writes the value one level up * searches for key -> value in an array tree and writes the value one level up
* this will remove this leaf will all other values * this will remove this leaf will all other values
* *
* @param array<mixed> $array nested array * @param array<mixed> $in_array nested array
* @param string|int $search key to find that has no sub leaf * @param string|int $search key to find that has no sub leaf
* and will be pushed up * and will be pushed up
* @return array<mixed> modified, flattened array * @return array<mixed> modified, flattened array
*/ */
public static function arrayFlatForKey(array $array, string|int $search): array public static function arrayFlatForKey(array $in_array, string|int $search): array
{ {
foreach ($array as $key => $value) { foreach ($in_array as $key => $value) {
// if it is not an array do just nothing // if it is not an array do just nothing
if (!is_array($value)) { if (!is_array($value)) {
continue; continue;
@@ -500,14 +660,156 @@ class ArrayHandler
// probe it has search key // probe it has search key
if (isset($value[$search])) { if (isset($value[$search])) {
// set as current // set as current
$array[$key] = $value[$search]; $in_array[$key] = $value[$search];
} else { } else {
// call up next node down // call up next node down
// $array[$key] = call_user_func(__METHOD__, $value, $search); // $in_array[$key] = call_user_func(__METHOD__, $value, $search);
$array[$key] = self::arrayFlatForKey($value, $search); $in_array[$key] = self::arrayFlatForKey($value, $search);
} }
} }
return $array; return $in_array;
}
/**
* Remove entries from a simple array, will not keep key order
*
* any array content is allowed
*
* https://stackoverflow.com/a/369608
*
* @param array<mixed> $in_array Array where elements are located
* @param array<mixed> $remove Elements to remove
* @return array<mixed> Array with $remove elements removed
*/
public static function arrayRemoveEntry(array $in_array, array $remove): array
{
return array_diff($in_array, $remove);
}
/**
* From the array with key -> mixed values,
* return only the entries where the key matches the key given in the key list parameter
*
* key list is a list[string]
* if key list is empty, return array as is
*
* @param array<string,mixed> $in_array
* @param array<string> $key_list
* @return array<string,mixed>
*/
public static function arrayReturnMatchingKeyOnly(
array $in_array,
array $key_list
): array {
// on empty return as is
if (empty($key_list)) {
return $in_array;
}
return array_filter(
$in_array,
fn($key) => in_array($key, $key_list),
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<string|int,mixed> $in_array
* @param string $key_mod_prefix [''] key prefix string
* @param string $key_mod_suffix [''] key suffix string
* @return array<string|int,mixed>
*/
public static function arrayModifyKey(
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)
);
}
/**
* sort array and return in same call
* sort ascending or descending with or without lower case convert
* value only, will loose key connections unless preserve_keys is set to true
*
* @param array<mixed> $in_array Array to sort by values
* @param bool $case_insensitive [false] Sort case insensitive
* @param bool $reverse [false] Reverse sort
* @param bool $maintain_keys [false] Maintain keys
* @param int $flag [SORT_REGULAR] Sort flags
* @return array<mixed>
*/
public static function sortArray(
array $in_array,
bool $case_insensitive = false,
bool $reverse = false,
bool $maintain_keys = false,
int $flag = SORT_REGULAR
): array {
$fk_sort_lower_case = function (string $a, string $b): int {
return strtolower($a) <=> strtolower($b);
};
$fk_sort_lower_case_reverse = function (string $a, string $b): int {
return strtolower($b) <=> strtolower($a);
};
$case_insensitive ? (
$maintain_keys ?
(uasort($in_array, $reverse ? $fk_sort_lower_case_reverse : $fk_sort_lower_case)) :
(usort($in_array, $reverse ? $fk_sort_lower_case_reverse : $fk_sort_lower_case))
) :
(
$maintain_keys ?
($reverse ? arsort($in_array, $flag) : asort($in_array, $flag)) :
($reverse ? rsort($in_array, $flag) : sort($in_array, $flag))
);
return $in_array;
}
/**
* sort by key ascending or descending and return
*
* @param array<mixed> $in_array Array to srt
* @param bool $case_insensitive [false] Sort keys case insenstive
* @param bool $reverse [false] Reverse key sort
* @return array<mixed>
*/
public static function ksortArray(array $in_array, bool $case_insensitive = false, bool $reverse = false): array
{
$fk_sort_lower_case = function (string $a, string $b): int {
return strtolower($a) <=> strtolower($b);
};
$fk_sort_lower_case_reverse = function (string $a, string $b): int {
return strtolower($b) <=> strtolower($a);
};
$fk_sort = function (string $a, string $b): int {
return $a <=> $b;
};
$fk_sort_reverse = function (string $a, string $b): int {
return $b <=> $a;
};
uksort(
$in_array,
$case_insensitive ?
($reverse ? $fk_sort_lower_case_reverse : $fk_sort_lower_case) :
($reverse ? $fk_sort_reverse : $fk_sort)
);
return $in_array;
} }
} }

View File

@@ -639,16 +639,26 @@ class DateTime
* *
* @param string $start_date valid start date (y/m/d) * @param string $start_date valid start date (y/m/d)
* @param string $end_date valid end 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 * @param bool $return_named [default=false] return array type, false (default), true for named
* @return array<mixed> 0/overall, 1/weekday, 2/weekend * @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( public static function calcDaysInterval(
string $start_date, string $start_date,
string $end_date, string $end_date,
bool $return_named = false bool $return_named = false,
bool $include_end_date = true,
bool $exclude_start_date = false
): array { ): array {
// pos 0 all, pos 1 weekday, pos 2 weekend // 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 // if anything invalid, return 0,0,0
try { try {
$start = new \DateTime($start_date); $start = new \DateTime($start_date);
@@ -659,19 +669,30 @@ class DateTime
'overall' => 0, 'overall' => 0,
'weekday' => 0, 'weekday' => 0,
'weekend' => 0, 'weekend' => 0,
'reverse' => false
]; ];
} else { } else {
return [0, 0, 0]; return $days;
} }
} }
// so we include the last day too, we need to add +1 second in the time // so we include the last day too, we need to add +1 second in the time
$end->setTime(0, 0, 1); // if start is before end, switch dates and flag
// if end date before start date, only this will be filled $days[3] = false;
$days[0] = $end->diff($start)->days; if ($start > $end) {
$days[1] = 0; $new_start = $end;
$days[2] = 0; $end = $start;
$start = $new_start;
$days[3] = true;
}
// get period for weekends/weekdays // 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) { foreach ($period as $dt) {
$curr = $dt->format('D'); $curr = $dt->format('D');
if ($curr == 'Sat' || $curr == 'Sun') { if ($curr == 'Sat' || $curr == 'Sun') {
@@ -679,18 +700,80 @@ class DateTime
} else { } else {
$days[1]++; $days[1]++;
} }
$days[0]++;
} }
if ($return_named === true) { if ($return_named === true) {
return [ return [
'overall' => $days[0], 'overall' => $days[0],
'weekday' => $days[1], 'weekday' => $days[1],
'weekend' => $days[2], 'weekend' => $days[2],
'reverse' => $days[3],
]; ];
} else { } else {
return $days; 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 * check if a weekend day (sat/sun) is in the given date range
* Can have time too, but is not needed * Can have time too, but is not needed
@@ -705,6 +788,13 @@ class DateTime
): bool { ): bool {
$dd_start = new \DateTime($start_date); $dd_start = new \DateTime($start_date);
$dd_end = new \DateTime($end_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 ( if (
// starts with a weekend // starts with a weekend
$dd_start->format('N') >= 6 || $dd_start->format('N') >= 6 ||

View File

@@ -14,6 +14,7 @@ class Byte
public const BYTE_FORMAT_NOSPACE = 1; public const BYTE_FORMAT_NOSPACE = 1;
public const BYTE_FORMAT_ADJUST = 2; public const BYTE_FORMAT_ADJUST = 2;
public const BYTE_FORMAT_SI = 4; public const BYTE_FORMAT_SI = 4;
public const RETURN_AS_STRING = 8;
/** /**
* This function replaces the old byteStringFormat * This function replaces the old byteStringFormat
@@ -77,7 +78,7 @@ class Byte
// labels in order of size [Y, Z] // labels in order of size [Y, Z]
$labels = ['', 'K', 'M', 'G', 'T', 'P', 'E']; $labels = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
// exp position calculation // exp position calculation
$exp = floor(log($abs_bytes, $unit)); $exp = (int)floor(log($abs_bytes, $unit));
// avoid printing out anything larger than max labels // avoid printing out anything larger than max labels
if ($exp >= count($labels)) { if ($exp >= count($labels)) {
$exp = count($labels) - 1; $exp = count($labels) - 1;
@@ -119,7 +120,9 @@ class Byte
* @param int $flags bitwise flag with use space turned on * @param int $flags bitwise flag with use space turned on
* BYTE_FORMAT_SI: use 1000 instead of 1024 * BYTE_FORMAT_SI: use 1000 instead of 1024
* @return string|int|float converted value or original value * @return string|int|float converted value or original value
* @throws \InvalidArgumentException 1: no valid flag set * @throws \InvalidArgumentException no valid flag set
* @throws \LengthException number too large to convert to int
* @throws \RuntimeException BCMath extension not loaded if flag is set to string
*/ */
public static function stringByteFormat(string|int|float $number, int $flags = 0): string|int|float public static function stringByteFormat(string|int|float $number, int $flags = 0): string|int|float
{ {
@@ -129,7 +132,12 @@ class Byte
} else { } else {
$si = false; $si = false;
} }
if ($flags != 0 && $flags != 4) { if ($flags & self::RETURN_AS_STRING) {
$return_as_string = true;
} else {
$return_as_string = false;
}
if ($flags != 0 && $flags != 4 && $flags != 8 && $flags != 12) {
throw new \InvalidArgumentException("Invalid flags parameter: $flags", 1); throw new \InvalidArgumentException("Invalid flags parameter: $flags", 1);
} }
// matches in regex // matches in regex
@@ -142,6 +150,10 @@ class Byte
strtolower((string)$number), strtolower((string)$number),
$matches $matches
); );
$number_negative = false;
if (!empty($matches[1])) {
$number_negative = true;
}
if (isset($matches[2]) && isset($matches[3])) { if (isset($matches[2]) && isset($matches[3])) {
// remove all non valid characters from the number // remove all non valid characters from the number
$number = preg_replace('/[^0-9\.]/', '', $matches[2]); $number = preg_replace('/[^0-9\.]/', '', $matches[2]);
@@ -152,12 +164,48 @@ class Byte
if ($unit) { if ($unit) {
$number = $number * pow($si ? 1000 : 1024, stripos($valid_units_, $unit[0]) ?: 0); $number = $number * pow($si ? 1000 : 1024, stripos($valid_units_, $unit[0]) ?: 0);
} }
// if the number is too large, we cannot convert to int directly
if ($number <= PHP_INT_MIN || $number >= PHP_INT_MAX) {
// if we do not want to convert to string
if (!$return_as_string) {
throw new \LengthException(
'Number too large be converted to int: ' . (string)$number
);
}
// for string, check if bcmath is loaded, if not this will not work
if (!extension_loaded('bcmath')) {
throw new \RuntimeException(
'Number too large be converted to int and BCMath extension not loaded: ' . (string)$number
);
}
}
// string return
if ($return_as_string) {
// return as string to avoid overflow
// $number = (string)round($number);
$number = bcmul(number_format(
$number,
12,
'.',
''
), "1");
if ($number_negative) {
$number = '-' . $number;
}
return $number;
}
// convert to INT to avoid +E output // convert to INT to avoid +E output
$number = (int)round($number); $number = (int)round($number);
// if negative input, keep nnegative // if negative input, keep nnegative
if (!empty($matches[1])) { if ($number_negative) {
$number *= -1; $number *= -1;
} }
// check if number is negative but should be, this is Lenght overflow
if (!$number_negative && $number < 0) {
throw new \LengthException(
'Number too large be converted to int: ' . (string)$number
);
}
} }
// if not matching return as is // if not matching return as is
return $number; return $number;

View File

@@ -17,6 +17,9 @@ declare(strict_types=1);
namespace CoreLibs\Convert; namespace CoreLibs\Convert;
use CoreLibs\Convert\Color\Color;
use CoreLibs\Convert\Color\Coordinates;
class Colors class Colors
{ {
/** /**
@@ -30,6 +33,7 @@ class Colors
* @param bool $hex_prefix default true, prefix with "#" * @param bool $hex_prefix default true, prefix with "#"
* @return string rgb in hex values with leading # if set, * @return string rgb in hex values with leading # if set,
* @throws \LengthException If any argument is not in the range of 0~255 * @throws \LengthException If any argument is not in the range of 0~255
* @deprecated v9.20.0 use: new Coordinates\RGB([$red, $green, $blue]))->returnAsHex(true/false for #)
*/ */
public static function rgb2hex( public static function rgb2hex(
int $red, int $red,
@@ -37,20 +41,7 @@ class Colors
int $blue, int $blue,
bool $hex_prefix = true bool $hex_prefix = true
): string { ): string {
$hex_color = ''; return (new Coordinates\RGB([$red, $green, $blue]))->returnAsHex($hex_prefix);
if ($hex_prefix === true) {
$hex_color = '#';
}
foreach (['red', 'green', 'blue'] as $color) {
// if not valid, abort
if ($$color < 0 || $$color > 255) {
throw new \LengthException('Argument value ' . $$color . ' for color ' . $color
. ' is not in the range of 0 to 255', 1);
}
// pad left with 0
$hex_color .= str_pad(dechex($$color), 2, '0', STR_PAD_LEFT);
}
return $hex_color;
} }
/** /**
@@ -63,32 +54,29 @@ class Colors
* or a string with the seperator * or a string with the seperator
* @throws \InvalidArgumentException if hex string is empty * @throws \InvalidArgumentException if hex string is empty
* @throws \UnexpectedValueException if the hex string value is not valid * @throws \UnexpectedValueException if the hex string value is not valid
* @deprecated v9.20.0 use: new Coordinates\RGB($hex_string) (build string/array from return data)
*/ */
public static function hex2rgb( public static function hex2rgb(
string $hex_string, string $hex_string,
bool $return_as_string = false, bool $return_as_string = false,
string $seperator = ',' string $seperator = ','
): string|array { ): string|array {
$hex_string = preg_replace("/[^0-9A-Fa-f]/", '', $hex_string); // Gets a proper hex string
if (!is_string($hex_string)) {
throw new \InvalidArgumentException('hex_string argument cannot be empty', 1);
}
$rgbArray = []; $rgbArray = [];
if (strlen($hex_string) == 6) { // rewrite to previous r/g/b key output
// If a proper hex code, convert using bitwise operation. foreach ((new Coordinates\RGB($hex_string))->returnAsArray() as $p => $el) {
// No overhead... faster $k = '';
$colorVal = hexdec($hex_string); switch ($p) {
$rgbArray['r'] = 0xFF & ($colorVal >> 0x10); case 0:
$rgbArray['g'] = 0xFF & ($colorVal >> 0x8); $k = 'r';
$rgbArray['b'] = 0xFF & $colorVal; break;
} elseif (strlen($hex_string) == 3) { case 1:
// If shorthand notation, need some string manipulations $k = 'g';
$rgbArray['r'] = hexdec(str_repeat(substr($hex_string, 0, 1), 2)); break;
$rgbArray['g'] = hexdec(str_repeat(substr($hex_string, 1, 1), 2)); case 2:
$rgbArray['b'] = hexdec(str_repeat(substr($hex_string, 2, 1), 2)); $k = 'b';
} else { break;
// Invalid hex color code }
throw new \UnexpectedValueException('Invalid hex_string: ' . $hex_string, 2); $rgbArray[$k] = (int)round($el);
} }
// returns the rgb string or the associative array // returns the rgb string or the associative array
return $return_as_string ? implode($seperator, $rgbArray) : $rgbArray; return $return_as_string ? implode($seperator, $rgbArray) : $rgbArray;
@@ -105,42 +93,16 @@ class Colors
* @param int $blue blue 0-255 * @param int $blue blue 0-255
* @return array<int|float> Hue, Sat, Brightness/Value * @return array<int|float> Hue, Sat, Brightness/Value
* @throws \LengthException If any argument is not in the range of 0~255 * @throws \LengthException If any argument is not in the range of 0~255
* @deprecated v9.20.0 use: Color::rgbToHsb(...)->returnAsArray() will return float unrounded
*/ */
public static function rgb2hsb(int $red, int $green, int $blue): array public static function rgb2hsb(int $red, int $green, int $blue): array
{ {
// check that rgb is from 0 to 255 return array_map(
foreach (['red', 'green', 'blue'] as $color) { fn ($v) => (int)round($v),
if ($$color < 0 || $$color > 255) { Color::rgbToHsb(
throw new \LengthException('Argument value ' . $$color . ' for color ' . $color new Coordinates\RGB([$red, $green, $blue])
. ' is not in the range of 0 to 255', 1); )->returnAsArray()
} );
$$color = $$color / 255;
}
$MAX = max($red, $green, $blue);
$MIN = min($red, $green, $blue);
$HUE = 0;
if ($MAX == $MIN) {
return [0, 0, round($MAX * 100)];
}
if ($red == $MAX) {
$HUE = ($green - $blue) / ($MAX - $MIN);
} elseif ($green == $MAX) {
$HUE = 2 + (($blue - $red) / ($MAX - $MIN));
} elseif ($blue == $MAX) {
$HUE = 4 + (($red - $green) / ($MAX - $MIN));
}
$HUE *= 60;
if ($HUE < 0) {
$HUE += 360;
}
return [
(int)round($HUE),
(int)round((($MAX - $MIN) / $MAX) * 100),
(int)round($MAX * 100)
];
} }
/** /**
@@ -153,80 +115,16 @@ class Colors
* @param float $V brightness/value 0-100 (int) * @param float $V brightness/value 0-100 (int)
* @return array<int> 0 red/1 green/2 blue array as 0-255 * @return array<int> 0 red/1 green/2 blue array as 0-255
* @throws \LengthException If any argument is not in the valid range * @throws \LengthException If any argument is not in the valid range
* @deprecated v9.20.0 use: Color::hsbToRgb(...)->returnAsArray() will return float unrounded
*/ */
public static function hsb2rgb(float $H, float $S, float $V): array public static function hsb2rgb(float $H, float $S, float $V): array
{ {
// check that H is 0 to 359, 360 = 0 return array_map(
// and S and V are 0 to 1 fn ($v) => (int)round($v),
if ($H == 360) { Color::hsbToRgb(
$H = 0; new Coordinates\HSB([$H, $S, $V])
} )->returnAsArray()
if ($H < 0 || $H > 359) { );
throw new \LengthException('Argument value ' . $H . ' for hue is not in the range of 0 to 359', 1);
}
if ($S < 0 || $S > 100) {
throw new \LengthException('Argument value ' . $S . ' for saturation is not in the range of 0 to 100', 2);
}
if ($V < 0 || $V > 100) {
throw new \LengthException('Argument value ' . $V . ' for brightness is not in the range of 0 to 100', 3);
}
// convert to internal 0-1 format
$S /= 100;
$V /= 100;
if ($S == 0) {
$V = (int)round($V * 255);
return [$V, $V, $V];
}
$Hi = floor($H / 60);
$f = ($H / 60) - $Hi;
$p = $V * (1 - $S);
$q = $V * (1 - ($S * $f));
$t = $V * (1 - ($S * (1 - $f)));
switch ($Hi) {
case 0:
$red = $V;
$green = $t;
$blue = $p;
break;
case 1:
$red = $q;
$green = $V;
$blue = $p;
break;
case 2:
$red = $p;
$green = $V;
$blue = $t;
break;
case 3:
$red = $p;
$green = $q;
$blue = $V;
break;
case 4:
$red = $t;
$green = $p;
$blue = $V;
break;
case 5:
$red = $V;
$green = $p;
$blue = $q;
break;
default:
$red = 0;
$green = 0;
$blue = 0;
}
return [
(int)round($red * 255),
(int)round($green * 255),
(int)round($blue * 255)
];
} }
/** /**
@@ -239,50 +137,16 @@ class Colors
* @param int $blue blue 0-255 * @param int $blue blue 0-255
* @return array<float> hue/sat/luminance * @return array<float> hue/sat/luminance
* @throws \LengthException If any argument is not in the range of 0~255 * @throws \LengthException If any argument is not in the range of 0~255
* @deprecated v9.20.0 use: Color::rgbToHsl(...)->returnAsArray() will return float unrounded
*/ */
public static function rgb2hsl(int $red, int $green, int $blue): array public static function rgb2hsl(int $red, int $green, int $blue): array
{ {
// check that rgb is from 0 to 255 return array_map(
foreach (['red', 'green', 'blue'] as $color) { fn ($v) => round($v, 1),
if ($$color < 0 || $$color > 255) { Color::rgbToHsl(
throw new \LengthException('Argument value ' . $$color . ' for color ' . $color new Coordinates\RGB([$red, $green, $blue])
. ' is not in the range of 0 to 255', 1); )->returnAsArray()
} );
$$color = $$color / 255;
}
$min = min($red, $green, $blue);
$max = max($red, $green, $blue);
$chroma = $max - $min;
$sat = 0;
$hue = 0;
// luminance
$lum = ($max + $min) / 2;
// achromatic
if ($chroma == 0) {
// H, S, L
return [0.0, 0.0, round($lum * 100, 1)];
} else {
$sat = $chroma / (1 - abs(2 * $lum - 1));
if ($max == $red) {
$hue = fmod((($green - $blue) / $chroma), 6);
if ($hue < 0) {
$hue = (6 - fmod(abs($hue), 6));
}
} elseif ($max == $green) {
$hue = ($blue - $red) / $chroma + 2;
} elseif ($max == $blue) {
$hue = ($red - $green) / $chroma + 4;
}
$hue = $hue * 60;
// $sat = 1 - abs(2 * $lum - 1);
return [
round($hue, 1),
round($sat * 100, 1),
round($lum * 100, 1)
];
}
} }
/** /**
@@ -294,57 +158,16 @@ class Colors
* @param float $lum luminance: 0-100 * @param float $lum luminance: 0-100
* @return array<int,float|int> red/blue/green 0-255 each * @return array<int,float|int> red/blue/green 0-255 each
* @throws \LengthException If any argument is not in the valid range * @throws \LengthException If any argument is not in the valid range
* @deprecated v9.20.0 use: Color::hslToRgb(...)->returnAsArray() will return float unrounded
*/ */
public static function hsl2rgb(float $hue, float $sat, float $lum): array public static function hsl2rgb(float $hue, float $sat, float $lum): array
{ {
if ($hue == 360) { return array_map(
$hue = 0; fn ($v) => round($v),
} Color::hslToRgb(
if ($hue < 0 || $hue > 359) { new Coordinates\HSL([$hue, $sat, $lum])
throw new \LengthException('Argument value ' . $hue . ' for hue is not in the range of 0 to 359', 1); )->returnAsArray()
} );
if ($sat < 0 || $sat > 100) {
throw new \LengthException('Argument value ' . $sat . ' for saturation is not in the range of 0 to 100', 2);
}
if ($lum < 0 || $lum > 100) {
throw new \LengthException('Argument value ' . $lum . ' for luminance is not in the range of 0 to 100', 3);
}
// calc to internal convert value for hue
$hue = (1 / 360) * $hue;
// convert to internal 0-1 format
$sat /= 100;
$lum /= 100;
// if saturation is 0
if ($sat == 0) {
$lum = (int)round($lum * 255);
return [$lum, $lum, $lum];
} else {
$m2 = $lum < 0.5 ? $lum * ($sat + 1) : ($lum + $sat) - ($lum * $sat);
$m1 = $lum * 2 - $m2;
$hueue = function ($base) use ($m1, $m2) {
// base = hue, hue > 360 (1) - 360 (1), else < 0 + 360 (1)
$base = $base < 0 ? $base + 1 : ($base > 1 ? $base - 1 : $base);
// 6: 60, 2: 180, 3: 240
// 2/3 = 240
// 1/3 = 120 (all from 360)
if ($base * 6 < 1) {
return $m1 + ($m2 - $m1) * $base * 6;
}
if ($base * 2 < 1) {
return $m2;
}
if ($base * 3 < 2) {
return $m1 + ($m2 - $m1) * ((2 / 3) - $base) * 6;
}
return $m1;
};
return [
(int)round(255 * $hueue($hue + (1 / 3))),
(int)round(255 * $hueue($hue)),
(int)round(255 * $hueue($hue - (1 / 3)))
];
}
} }
} }

View File

@@ -23,14 +23,14 @@ class Encoding
* @param bool $auto_check default true, if source encoding is set * @param bool $auto_check default true, if source encoding is set
* check that the source is actually matching * check that the source is actually matching
* to what we sav the source is * to what we sav the source is
* @return string encoding converted string * @return string|false encoding converted string or false on error
*/ */
public static function convertEncoding( public static function convertEncoding(
string $string, string $string,
string $to_encoding, string $to_encoding,
string $source_encoding = '', string $source_encoding = '',
bool $auto_check = true bool $auto_check = true
): string { ): string|false {
// set if not given // set if not given
if (!$source_encoding) { if (!$source_encoding) {
$source_encoding = mb_detect_encoding($string); $source_encoding = mb_detect_encoding($string);

View File

@@ -52,7 +52,7 @@ class SetVarTypeMain
*/ */
protected static function makeStrMain( protected static function makeStrMain(
mixed $val, mixed $val,
string $default = null, ?string $default = null,
bool $to_null = false bool $to_null = false
): ?string { ): ?string {
// int/float/string/bool/null, everything else is ignored // int/float/string/bool/null, everything else is ignored
@@ -113,7 +113,7 @@ class SetVarTypeMain
*/ */
protected static function makeIntMain( protected static function makeIntMain(
mixed $val, mixed $val,
int $default = null, ?int $default = null,
bool $to_null = false bool $to_null = false
): ?int { ): ?int {
// if we can filter it to a valid int, we can convert it // if we can filter it to a valid int, we can convert it
@@ -167,7 +167,7 @@ class SetVarTypeMain
*/ */
protected static function makeFloatMain( protected static function makeFloatMain(
mixed $val, mixed $val,
float $default = null, ?float $default = null,
bool $to_null = false bool $to_null = false
): ?float { ): ?float {
if ( if (

View File

@@ -10,9 +10,16 @@ namespace CoreLibs\Convert;
class Html class Html
{ {
/** @var int */
public const SELECTED = 0; public const SELECTED = 0;
/** @var int */
public const CHECKED = 1; 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<string> */
// public const VALID_HTMLENT_ENCODINGS = [];
/** /**
* full wrapper for html entities * full wrapper for html entities
* *
@@ -22,14 +29,19 @@ class Html
* encodes in UTF-8 * encodes in UTF-8
* does not double encode * does not double encode
* *
* @param mixed $string string to html encode * @param mixed $string string to html encode
* @param int $flags [default: ENT_QUOTES | ENT_HTML5] * @param int $flags [default=ENT_QUOTES | ENT_HTML5]
* @param string $encoding [default=UTF-8]
* @return mixed if string, encoded, else as is (eg null) * @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)) { 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; return $string;
} }
@@ -37,7 +49,7 @@ class Html
/** /**
* strips out all line breaks or replaced with given string * strips out all line breaks or replaced with given string
* @param string $string 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 * @return string cleaned string without any line breaks
*/ */
public static function removeLB(string $string, string $replace = ' '): string public static function removeLB(string $string, string $replace = ' '): string

View File

@@ -55,10 +55,10 @@ class Json
* Deos not throw errors * Deos not throw errors
* *
* @param array<mixed> $data * @param array<mixed> $data
* @param int $flags json_encode flags as is * @param int $flags [JSON_UNESCAPED_UNICODE] json_encode flags as is
* @return string JSON string or '{}' if false * @return string JSON string or '{}' if false
*/ */
public static function jsonConvertArrayTo(array $data, int $flags = 0): string public static function jsonConvertArrayTo(array $data, int $flags = JSON_UNESCAPED_UNICODE): string
{ {
$json_string = json_encode($data, $flags) ?: '{}'; $json_string = json_encode($data, $flags) ?: '{}';
self::$json_last_error = json_last_error(); self::$json_last_error = json_last_error();
@@ -119,6 +119,23 @@ class Json
} }
return $return_string === true ? $json_error_string : self::$json_last_error; return $return_string === true ? $json_error_string : self::$json_last_error;
} }
/**
* wrapper to call convert array to json with pretty print
*
* @param array<mixed> $data
* @return string
*/
public static function jsonPrettyPrint(array $data): string
{
return self::jsonConvertArrayTo(
$data,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_LINE_TERMINATORS |
JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE
);
}
} }
// __END__ // __END__

View File

@@ -56,6 +56,187 @@ class Math
return (float)$number; return (float)$number;
} }
} }
/**
* calc cube root
*
* @param float $number Number to cubic root
* @return float Calculated value
* @throws \InvalidArgumentException if $number is negative
*/
public static function cbrt(float|int $number): float
{
$value = pow((float)$number, 1.0 / 3);
if (is_nan($value)) {
throw new \InvalidArgumentException('cube root from this number is not supported: ' . $number);
}
return $value;
}
/**
* use PHP_FLOAT_EPSILON to compare if two float numbers are matching
*
* @param float $x
* @param float $y
* @param float $epsilon [default=PHP_FLOAT_EPSILON]
* @return bool True equal
*/
public static function equalWithEpsilon(float $x, float $y, float $epsilon = PHP_FLOAT_EPSILON): bool
{
if (abs($x - $y) < $epsilon) {
return true;
}
return false;
}
/**
* Compare two value base on direction given
* The default delta is PHP_FLOAT_EPSILON
*
* @param float $value
* @param string $compare
* @param float $limit
* @param float $epsilon [default=PHP_FLOAT_EPSILON]
* @return bool True on smaller/large or equal
*/
public static function compareWithEpsilon(
float $value,
string $compare,
float $limit,
float $epsilon = PHP_FLOAT_EPSILON
): bool {
switch ($compare) {
case '<':
if ($value < ($limit - $epsilon)) {
return true;
}
break;
case '<=':
if ($value <= ($limit - $epsilon)) {
return true;
}
break;
case '==':
return self::equalWithEpsilon($value, $limit, $epsilon);
case '>':
if ($value > ($limit + $epsilon)) {
return true;
}
break;
case '>=':
if ($value >= ($limit + $epsilon)) {
return true;
}
break;
}
return false;
}
/**
* This function is directly inspired by the multiplyMatrices() function in color.js
* form Lea Verou and Chris Lilley.
* (see https://github.com/LeaVerou/color.js/blob/main/src/multiply-matrices.js)
* From:
* https://github.com/matthieumastadenis/couleur/blob/3842cf51c9517e77afaa0a36ec78643a0c258e0b/src/utils/utils.php#L507
*
* It returns an array which is the product of the two number matrices passed as parameters.
*
* NOTE:
* if the right side (B matrix) has a missing row, this row will be fillwed with 0 instead of
* throwing an error:
* A:
* [
* [1, 2, 3],
* [4, 5, 6],
* ]
* B:
* [
* [7, 8, 9],
* [10, 11, 12],
* ]
* The B will get a third row with [0, 0, 0] added to make the multiplication work as it will be
* rewritten as
* B-rewrite:
* [
* [7, 10, 0],
* [8, 11, 12],
* [0, 0, 0] <- automatically added
* ]
*
* The same is done for unbalanced entries, they are filled with 0
*
* @param array<float|int|array<int|float>> $a m x n matrice
* @param array<float|int|array<int|float>> $b n x p matrice
*
* @return array<float|int|array<int|float>> m x p product
*/
public static function multiplyMatrices(array $a, array $b): array
{
$m = count($a);
if (!is_array($a[0] ?? null)) {
// $a is vector, convert to [[a, b, c, ...]]
$a = [$a];
}
if (!is_array($b[0])) {
// $b is vector, convert to [[a], [b], [c], ...]]
$b = array_map(
callback: fn ($v) => [ $v ],
array: $b,
);
}
$p = count($b[0]);
// transpose $b:
// so that we can multiply row by row
$bCols = array_map(
callback: fn ($k) => array_map(
(fn ($i) => is_array($i) ? $i[$k] ?? 0 : 0),
$b,
),
array: array_keys($b[0]),
);
$product = array_map(
callback: fn ($row) => array_map(
callback: fn ($col) => is_array($row) ?
array_reduce(
array: $row,
// TODO check that v is not an array
callback: fn ($a, $v, $i = null) => $a + $v * ( /** @phpstan-ignore-line Possible array + int */
// if last entry missing for full copy add a 0 to it
$col[$i ?? array_search($v, $row, true)] ?? 0
),
initial: 0,
) :
array_reduce(
array: $col,
// TODO check that v is not an array
callback: fn ($a, $v) => $a + $v * $row, /** @phpstan-ignore-line Possible array + int */
initial: 0,
),
array: $bCols,
),
array: $a,
);
if ($m === 1) {
// Avoid [[a, b, c, ...]]:
return $product[0];
}
if ($p === 1) {
// Avoid [[a], [b], [c], ...]]:
return array_map(
callback: fn ($v) => $v[0] ?? 0,
array: $product,
);
}
return $product;
}
} }
// __END__ // __END__

View File

@@ -35,7 +35,7 @@ class SetVarTypeNull extends Extends\SetVarTypeMain
* @param string|null $default Default override value * @param string|null $default Default override value
* @return string|null Input value as string or default as string/null * @return string|null Input value as string or default as string/null
*/ */
public static function makeStr(mixed $val, string $default = null): ?string public static function makeStr(mixed $val, ?string $default = null): ?string
{ {
return SetVarTypeMain::makeStrMain($val, $default, true); return SetVarTypeMain::makeStrMain($val, $default, true);
} }
@@ -60,7 +60,7 @@ class SetVarTypeNull extends Extends\SetVarTypeMain
* @param int|null $default Default override value * @param int|null $default Default override value
* @return int|null Input value as int or default as int/null * @return int|null Input value as int or default as int/null
*/ */
public static function makeInt(mixed $val, int $default = null): ?int public static function makeInt(mixed $val, ?int $default = null): ?int
{ {
return SetVarTypeMain::makeIntMain($val, $default, true); return SetVarTypeMain::makeIntMain($val, $default, true);
} }
@@ -84,7 +84,7 @@ class SetVarTypeNull extends Extends\SetVarTypeMain
* @param float|null $default Default override value * @param float|null $default Default override value
* @return float|null Input value as float or default as float/null * @return float|null Input value as float or default as float/null
*/ */
public static function makeFloat(mixed $val, float $default = null): ?float public static function makeFloat(mixed $val, ?float $default = null): ?float
{ {
return SetVarTypeMain::makeFloatMain($val, $default, true); return SetVarTypeMain::makeFloatMain($val, $default, true);
} }

View File

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

View File

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

View File

@@ -10,9 +10,14 @@ namespace CoreLibs\Create;
class Hash class Hash
{ {
/** @var string default short hash -> deprecated use STANDARD_HASH_SHORT */
public const DEFAULT_HASH = 'adler32'; public const DEFAULT_HASH = 'adler32';
/** @var string default long hash (40 chars) */
public const STANDARD_HASH_LONG = 'ripemd160'; public const STANDARD_HASH_LONG = 'ripemd160';
/** @var string default short hash (8 chars) */
public const STANDARD_HASH_SHORT = 'adler32'; 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 * checks php version and if >=5.2.7 it will flip the string
@@ -20,6 +25,7 @@ class Hash
* hash returns false * hash returns false
* preg_replace fails for older php version * preg_replace fails for older php version
* Use __hash with crc32b or hash('crc32b', ...) for correct output * Use __hash with crc32b or hash('crc32b', ...) for correct output
* For future short hashes use hashShort() instead
* *
* @param string $string string to crc * @param string $string string to crc
* @return string crc32b hash (old type) * @return string crc32b hash (old type)
@@ -43,19 +49,31 @@ class Hash
* replacement for __crc32b call * replacement for __crc32b call
* *
* @param string $string string to hash * @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 * @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 public static function __sha1Short(string $string, bool $use_sha = false): string
{ {
if ($use_sha) { if ($use_sha) {
// return only the first 9 characters return self::sha1Short($string);
return substr(hash('sha1', $string), 0, 9);
} else { } else {
return self::__crc32b($string); 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) * replacemend for __crc32b call (alternate)
* defaults to adler 32 * defaults to adler 32
@@ -63,34 +81,135 @@ class Hash
* all that create 8 char long hashes * all that create 8 char long hashes
* *
* @param string $string string to hash * @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 * @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( public static function __hash(
string $string, 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 { ): string {
// if not empty, check if in valid list
if ( if (
empty($hash_type) || empty($hash_type) ||
!in_array($hash_type, hash_algos()) !in_array($hash_type, hash_algos())
) { ) {
// fallback to default hash type if none set or invalid // fallback to default hash type if empty or invalid
$hash_type = self::DEFAULT_HASH; $hash_type = self::STANDARD_HASH;
} }
return hash($hash_type, $string); 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 * @param string $string String to be hashed
* @return string Hashed string * @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); 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__ // __END__

View File

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

View File

@@ -15,17 +15,111 @@ namespace CoreLibs\Create;
class Session class Session
{ {
/** @var string current session name */
private string $session_name = '';
/** @var string current session id */
private string $session_id = '';
/** @var bool flag auto write close */
private bool $auto_write_close = false;
/** @var string regenerate option, default never */
private string $regenerate = 'never';
/** @var int regenerate interval either 1 to 100 for random or 0 to 3600 for interval */
private int $regenerate_interval = 0;
/** @var array<string> allowed session id regenerate (rotate) options */
private const ALLOWED_REGENERATE_OPTIONS = ['none', 'random', 'interval'];
/** @var int default random interval */
public const DEFAULT_REGENERATE_RANDOM = 100;
/** @var int default rotate internval in minutes */
public const DEFAULT_REGENERATE_INTERVAL = 5 * 60;
/** @var int maximum time for regenerate interval is one hour */
public const MAX_REGENERATE_INTERAL = 60 * 60;
/** /**
* init a session, if array is empty or array does not have session_name set * init a session, if array is empty or array does not have session_name set
* then no auto init is run * then no auto init is run
* *
* @param string $session_name if set and not empty, will start session * @param string $session_name if set and not empty, will start session
* @param array{auto_write_close?:bool,session_strict?:bool,regenerate?:string,regenerate_interval?:int} $options
*/ */
public function __construct(string $session_name = '') public function __construct(
string $session_name,
array $options = []
) {
$this->setOptions($options);
$this->initSession($session_name);
}
// MARK: private methods
/**
* set session class options
*
* @param array{auto_write_close?:bool,session_strict?:bool,regenerate?:string,regenerate_interval?:int} $options
* @return void
*/
private function setOptions(array $options): void
{ {
if (!empty($session_name)) { if (
$this->startSession($session_name); !isset($options['auto_write_close']) ||
!is_bool($options['auto_write_close'])
) {
$options['auto_write_close'] = false;
} }
$this->auto_write_close = $options['auto_write_close'];
if (
!isset($options['session_strict']) ||
!is_bool($options['session_strict'])
) {
$options['session_strict'] = true;
}
// set strict options, on not started sessiononly
if (
$options['session_strict'] &&
$this->getSessionStatus() === PHP_SESSION_NONE
) {
// use cookies to store session IDs
ini_set('session.use_cookies', 1);
// use cookies only (do not send session IDs in URLs)
ini_set('session.use_only_cookies', 1);
// do not send session IDs in URLs
ini_set('session.use_trans_sid', 0);
}
// session regenerate id options
if (
empty($options['regenerate']) ||
!in_array($options['regenerate'], self::ALLOWED_REGENERATE_OPTIONS)
) {
$options['regenerate'] = 'never';
}
$this->regenerate = (string)$options['regenerate'];
// for regenerate: 'random' (default 100)
// regenerate_interval must be between (1 = always) and 100 (1 in 100)
// for regenerate: 'interval' (default 5min)
// regenerate_interval must be 0 = always, to 3600 (every hour)
if (
$options['regenerate'] == 'random' &&
(
!isset($options['regenerate_interval']) ||
!is_numeric($options['regenerate_interval']) ||
$options['regenerate_interval'] < 0 ||
$options['regenerate_interval'] > 100
)
) {
$options['regenerate_interval'] = self::DEFAULT_REGENERATE_RANDOM;
}
if (
$options['regenerate'] == 'interval' &&
(
!isset($options['regenerate_interval']) ||
!is_numeric($options['regenerate_interval']) ||
$options['regenerate_interval'] < 1 ||
$options['regenerate_interval'] > self::MAX_REGENERATE_INTERAL
)
) {
$options['regenerate_interval'] = self::DEFAULT_REGENERATE_INTERVAL;
}
$this->regenerate_interval = (int)($options['regenerate_interval'] ?? 0);
} }
/** /**
@@ -36,38 +130,100 @@ class Session
* *
* @return void * @return void
*/ */
protected function startSessionCall(): void private function startSessionCall(): void
{ {
session_start(); session_start();
} }
/** /**
* check if we are in CLI, we set this, so we can mock this * get current set session id or false if none started
* Not this is just a wrapper for the static System::checkCLI call
* *
* @return bool True if we are in a CLI enviroment, or false for everything else * @return string|false
*/ */
public function checkCliStatus(): bool public function getSessionIdCall(): string|false
{ {
return \CoreLibs\Get\System::checkCLI(); return session_id();
} }
/** /**
* Set session name call. If not valid session name, will return false * automatically closes a session if the auto write close flag is set
* *
* @param string $session_name A valid string for session name * @return bool
* @return bool True if session name is valid,
* False if not
*/ */
public function setSessionName(string $session_name): bool private function closeSessionCall(): bool
{ {
if (!$this->checkValidSessionName($session_name)) { if ($this->auto_write_close) {
return false; return $this->writeClose();
} }
session_name($session_name); return false;
return true;
} }
// MARK: regenerate session
/**
* auto rotate session id
*
* @return void
* @throws \RuntimeException failure to regenerate session id
* @throws \UnexpectedValueException failed to get new session id
* @throws \RuntimeException failed to set new sesson id
* @throws \UnexpectedValueException new session id generated does not match the new set one
*/
private function sessionRegenerateSessionId()
{
// never
if ($this->regenerate == 'never') {
return;
}
// regenerate
if (
!(
// is not session obsolete
empty($_SESSION['SESSION_REGENERATE_OBSOLETE']) &&
(
(
// random
$this->regenerate == 'random' &&
mt_rand(1, $this->regenerate_interval) == 1
) || (
// interval type
$this->regenerate == 'interval' &&
($_SESSION['SESSION_REGENERATE_TIMESTAMP'] ?? 0) + $this->regenerate_interval < time()
)
)
)
) {
return;
}
// Set current session to expire in 1 minute
$_SESSION['SESSION_REGENERATE_OBSOLETE'] = true;
$_SESSION['SESSION_REGENERATE_EXPIRES'] = time() + 60;
$_SESSION['SESSION_REGENERATE_TIMESTAMP'] = time();
// Create new session without destroying the old one
if (session_regenerate_id(false) === false) {
throw new \RuntimeException('[SESSION] Session id regeneration failed', 1);
}
// Grab current session ID and close both sessions to allow other scripts to use them
if (false === ($new_session_id = $this->getSessionIdCall())) {
throw new \UnexpectedValueException('[SESSION] getSessionIdCall did not return a session id', 2);
}
$this->writeClose();
// Set session ID to the new one, and start it back up again
if (($get_new_session_id = session_id($new_session_id)) === false) {
throw new \RuntimeException('[SESSION] set session_id failed', 3);
}
if ($get_new_session_id != $new_session_id) {
throw new \UnexpectedValueException('[SESSION] new session id does not match the new set one', 4);
}
$this->session_id = $new_session_id;
$this->startSessionCall();
// Don't want this one to expire
unset($_SESSION['SESSION_REGENERATE_OBSOLETE']);
unset($_SESSION['SESSION_REGENERATE_EXPIRES']);
}
// MARK: session validation
/** /**
* check if session name is valid * check if session name is valid
* *
@@ -94,15 +250,34 @@ class Session
} }
/** /**
* start session with given session name if set * validate _SESSION key, must be valid variable
*
* @param int|float|string $key
* @return true
*/
private function checkValidSessionEntryKey(int|float|string $key): true
{
if (!is_string($key) || is_numeric($key)) {
throw new \UnexpectedValueException(
'[SESSION] Given key for _SESSION is not a valid value for a varaible: ' . $key,
1
);
}
return true;
}
// MARK: init session (on class start)
/**
* stinitart session with given session name if set
* aborts on command line or if sessions are not enabled * aborts on command line or if sessions are not enabled
* also aborts if session cannot be started * also aborts if session cannot be started
* On sucess returns the session id * On sucess returns the session id
* *
* @param string|null $session_name * @param string $session_name
* @return string|bool * @return void
*/ */
public function startSession(?string $session_name = null): string|bool private function initSession(string $session_name): void
{ {
// we can't start sessions on command line // we can't start sessions on command line
if ($this->checkCliStatus()) { if ($this->checkCliStatus()) {
@@ -115,39 +290,95 @@ class Session
// session_status // session_status
// initial the session if there is no session running already // initial the session if there is no session running already
if (!$this->checkActiveSession()) { if (!$this->checkActiveSession()) {
// if session name is emtpy, check if there is a global set // invalid session name, abort
// this is a deprecated fallback if (!$this->checkValidSessionName($session_name)) {
$session_name = $session_name ?? $GLOBALS['SET_SESSION_NAME'] ?? ''; throw new \UnexpectedValueException('[SESSION] Invalid session name: ' . $this->session_name, 3);
// DEPRECTED: constant SET_SESSION_NAME is no longer used
// if set, set special session name
if (!empty($session_name)) {
// invalid session name, abort
if (!$this->checkValidSessionName($session_name)) {
throw new \UnexpectedValueException('[SESSION] Invalid session name: ' . $session_name, 3);
}
$this->setSessionName($session_name);
} }
// set session name
$this->session_name = $session_name;
session_name($this->session_name);
// start session // start session
$this->startSessionCall(); $this->startSessionCall();
// if we faild to start the session
if (!$this->checkActiveSession()) {
throw new \RuntimeException('[SESSION] Failed to activate session', 5);
}
if (
!empty($_SESSION['SESSION_REGENERATE_OBSOLETE']) &&
!empty($_SESSION['SESSION_REGENERATE_EXPIRES']) && $_SESSION['SESSION_REGENERATE_EXPIRES'] < time()
) {
$this->sessionDestroy();
throw new \RuntimeException('[SESSION] Expired session found', 6);
}
} elseif ($session_name != $this->getSessionName()) {
throw new \UnexpectedValueException(
'[SESSION] Another session exists with a different name: ' . $this->getSessionName(),
4
);
} }
// if we still have no active session // check session id
if (false === ($session_id = $this->getSessionIdCall())) {
throw new \UnexpectedValueException('[SESSION] getSessionIdCall did not return a session id', 7);
}
// set session id
$this->session_id = $session_id;
// run session id re-create from time to time
$this->sessionRegenerateSessionId();
// if flagged auto close, write close session
if ($this->auto_write_close) {
$this->writeClose();
}
}
// MARK: public set/get status
/**
* start session, will only run after initSession
*
* @return bool True if started, False if alrady running
*/
public function restartSession(): bool
{
if (!$this->checkActiveSession()) { if (!$this->checkActiveSession()) {
throw new \RuntimeException('[SESSION] Failed to activate session', 4); if (empty($this->session_name)) {
throw new \RuntimeException('[SESSION] Cannot restart session without a session name', 1);
}
$this->startSessionCall();
return true;
} }
if (false === ($session_id = $this->getSessionId())) { return false;
throw new \UnexpectedValueException('[SESSION] getSessionId did not return a session id', 5);
}
return $session_id;
} }
/** /**
* get current set session id or false if none started * current set session id
* *
* @return string|bool * @return string
*/ */
public function getSessionId(): string|bool public function getSessionId(): string
{ {
return session_id(); return $this->session_id;
}
/**
* set the auto write close flag
*
* @param bool $flag
* @return Session
*/
public function setAutoWriteClose(bool $flag): Session
{
$this->auto_write_close = $flag;
return $this;
}
/**
* return the auto write close flag
*
* @return bool
*/
public function checkAutoWriteClose(): bool
{
return $this->auto_write_close;
} }
/** /**
@@ -175,6 +406,34 @@ class Session
} }
} }
/**
* check if we are in CLI, we set this, so we can mock this
* Not this is just a wrapper for the static System::checkCLI call
*
* @return bool True if we are in a CLI enviroment, or false for everything else
*/
public function checkCliStatus(): bool
{
return \CoreLibs\Get\System::checkCLI();
}
/**
* get session status
* PHP_SESSION_DISABLED if sessions are disabled.
* PHP_SESSION_NONE if sessions are enabled, but none exists.
* PHP_SESSION_ACTIVE if sessions are enabled, and one exists.
*
* https://www.php.net/manual/en/function.session-status.php
*
* @return int See possible return int values above
*/
public function getSessionStatus(): int
{
return session_status();
}
// MARK: write close session
/** /**
* unlock the session file, so concurrent AJAX requests can be done * unlock the session file, so concurrent AJAX requests can be done
* NOTE: after this has been called, no changes in _SESSION will be stored * NOTE: after this has been called, no changes in _SESSION will be stored
@@ -188,17 +447,24 @@ class Session
return session_write_close(); return session_write_close();
} }
// MARK: session close and clean up
/** /**
* Proper destroy a session * Proper destroy a session
* - unset the _SESSION array * - unset the _SESSION array
* - unset cookie if cookie on and we have not strict mode * - unset cookie if cookie on and we have not strict mode
* - unset session_name and session_id internal vars
* - destroy session * - destroy session
* *
* @return bool * @return bool True on successful session destroy
*/ */
public function sessionDestroy(): bool public function sessionDestroy(): bool
{ {
$_SESSION = []; // abort to false if not unsetable
if (!session_unset()) {
return false;
}
$this->clear();
if ( if (
ini_get('session.use_cookies') && ini_get('session.use_cookies') &&
!ini_get('session.use_strict_mode') !ini_get('session.use_strict_mode')
@@ -218,68 +484,93 @@ class Session
$params['httponly'] $params['httponly']
); );
} }
// unset internal vars
$this->session_name = '';
$this->session_id = '';
return session_destroy(); return session_destroy();
} }
/** // MARK: _SESSION set/unset methods
* get session status
* PHP_SESSION_DISABLED if sessions are disabled.
* PHP_SESSION_NONE if sessions are enabled, but none exists.
* PHP_SESSION_ACTIVE if sessions are enabled, and one exists.
*
* https://www.php.net/manual/en/function.session-status.php
*
* @return int See possible return int values above
*/
public function getSessionStatus(): int
{
return session_status();
}
// _SESSION set/unset methods
/** /**
* unset all _SESSION entries * unset all _SESSION entries
* *
* @return void * @return void
*/ */
public function unsetAllS(): void public function clear(): void
{ {
foreach (array_keys($_SESSION ?? []) as $name) { $this->restartSession();
unset($_SESSION[$name]); if (!session_unset()) {
throw new \RuntimeException('[SESSION] Cannot unset session vars', 1);
} }
if (!empty($_SESSION)) {
$_SESSION = [];
}
$this->closeSessionCall();
} }
/** /**
* set _SESSION entry 'name' with any value * set _SESSION entry 'name' with any value
* *
* @param string|int $name array name in _SESSION * @param string $name array name in _SESSION
* @param mixed $value value to set (can be anything) * @param mixed $value value to set (can be anything)
* @return Session
*/
public function set(string $name, mixed $value): Session
{
$this->checkValidSessionEntryKey($name);
$this->restartSession();
$_SESSION[$name] = $value;
$this->closeSessionCall();
return $this;
}
/**
* set many session entries in one set
*
* @param array<string,mixed> $set key is the key in the _SESSION, value is any data to set
* @return void * @return void
*/ */
public function setS(string|int $name, mixed $value): void public function setMany(array $set): void
{ {
$_SESSION[$name] = $value; $this->restartSession();
// skip any that are not valid
foreach ($set as $key => $value) {
$this->checkValidSessionEntryKey($key);
$_SESSION[$key] = $value;
}
$this->closeSessionCall();
} }
/** /**
* get _SESSION 'name' entry or empty string if not set * get _SESSION 'name' entry or empty string if not set
* *
* @param string|int $name value key to get from _SESSION * @param string $name value key to get from _SESSION
* @return mixed value stored in _SESSION * @return mixed value stored in _SESSION, if not found set to null
*/ */
public function getS(string|int $name): mixed public function get(string $name): mixed
{ {
return $_SESSION[$name] ?? ''; return $_SESSION[$name] ?? null;
}
/**
* get multiple session entries
*
* @param array<string> $set
* @return array<string,mixed>
*/
public function getMany(array $set): array
{
return array_intersect_key($_SESSION, array_flip($set));
} }
/** /**
* Check if a name is set in the _SESSION array * Check if a name is set in the _SESSION array
* *
* @param string|int $name Name to check for * @param string $name Name to check for
* @return bool True for set, False fornot set * @return bool True for set, False fornot set
*/ */
public function issetS(string|int $name): bool public function isset(string $name): bool
{ {
return isset($_SESSION[$name]); return isset($_SESSION[$name]);
} }
@@ -287,67 +578,36 @@ class Session
/** /**
* unset one _SESSION entry 'name' if exists * unset one _SESSION entry 'name' if exists
* *
* @param string|int $name _SESSION key name to remove * @param string $name _SESSION key name to remove
* @return Session
*/
public function unset(string $name): Session
{
if (!isset($_SESSION[$name])) {
return $this;
}
$this->restartSession();
unset($_SESSION[$name]);
$this->closeSessionCall();
return $this;
}
/**
* reset many session entry
*
* @param array<string> $set list of session keys to reset
* @return void * @return void
*/ */
public function unsetS(string|int $name): void public function unsetMany(array $set): void
{ {
if (isset($_SESSION[$name])) { $this->restartSession();
unset($_SESSION[$name]); foreach ($set as $key) {
} if (!isset($_SESSION[$key])) {
} continue;
}
// set/get below unset($_SESSION[$key]);
// ->var = value;
/**
* Undocumented function
*
* @param string|int $name
* @param mixed $value
* @return void
*/
public function __set(string|int $name, mixed $value): void
{
$_SESSION[$name] = $value;
}
/**
* Undocumented function
*
* @param string|int $name
* @return mixed If name is not found, it will return null
*/
public function __get(string|int $name): mixed
{
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
}
return null;
}
/**
* Undocumented function
*
* @param string|int $name
* @return bool
*/
public function __isset(string|int $name): bool
{
return isset($_SESSION[$name]);
}
/**
* Undocumented function
*
* @param string|int $name
* @return void
*/
public function __unset(string|int $name): void
{
if (isset($_SESSION[$name])) {
unset($_SESSION[$name]);
} }
$this->closeSessionCall();
} }
} }

Some files were not shown because too many files have changed in this diff Show More