Compare commits

...

31 Commits

Author SHA1 Message Date
Clemens Schwaighofer
cf1989819a phpstan fixes 2025-04-01 11:22:59 +09:00
Clemens Schwaighofer
b302fb4053 Add CombinedDateTime class calcDaysInteral wrapper functions
calcDaysIntervalNamedIndex for force using named index and returning only named index
calcDaysIntervalNumIndex for force using numeric index and returning only numeric index
2025-04-01 11:15:00 +09:00
Clemens Schwaighofer
32decdd037 Readme update 2025-03-28 10:58:07 +09:00
Clemens Schwaighofer
46cda40d37 JavaScript general utils file updates 2025-03-28 10:53:42 +09:00
Clemens Schwaighofer
e71df90144 Fully deprecate prototype edit.js, add deprecation warnings to edit.jq.js and add new utils
Note that all the utils.js are build in an external repository and just copied here
2025-03-10 11:00:02 +09:00
Clemens Schwaighofer
bbcc642fde All "edit.js" development has moved to a new repository
"Code-Blocks.javascript-utils"
2025-03-07 15:09:47 +09:00
Clemens Schwaighofer
558694aa6c Fix DEFAULT_ENCODING that it is string 2025-02-28 10:32:43 +09:00
Clemens Schwaighofer
f3bd09529a phpstan fixes 2025-02-28 10:29:04 +09:00
Clemens Schwaighofer
816bb7c9ee Allow encoding ovrride for htmlentities 2025-02-28 10:19:36 +09:00
Clemens Schwaighofer
fc7b705355 config.master.php file update
- remove not used code
- reorder defines for possible clean up targets
- TARGET and HOST_NAME are set early
HOST NAME is set right at the top
TARGET is set after site configs is read
- add more $_ENV reads
DEFAULT_ACL_LEVEL
LOCALE (encoding is read from locale which should be in the format of nn_CT.ENCODING, eg en_US.UTF-8), falls back to UTF-8
ADMIN.STYLESHEET
ADMIN.JAVASCRIPT
2025-02-28 10:17:10 +09:00
Clemens Schwaighofer
7b96c1f9ca Remove old eslint config, replaced with mjs one 2025-02-17 12:55:20 +09:00
Clemens Schwaighofer
26c6ebcea7 Merge branch 'NewFeatures' into Update-eslintrcToFlatLayout 2025-02-17 12:54:23 +09:00
Clemens Schwaighofer
32dee1692e Fix DateTime days internal counter
Fixed the bad coded include end date with using flags instead
Allow exclude of start date
Reverse counter fixed, and also includes weekend days

Add reverse for weekend in date interval

Login class: add numeric for ACL level

DB IO: some minor code clean up for not needed var set check

Some edit.jq.js clean ups and added
- loadEl: load element by id and return element value or throw error if not found
- goTo: scroll to an element with scroll into view call
2025-02-17 11:16:51 +09:00
Clemens Schwaighofer
6291ed88c0 eslint config update 2025-02-13 19:01:44 +09:00
Clemens Schwaighofer
5e21ead6fa change error catcher for javasript from log to error as output 2025-02-13 18:24:50 +09:00
Clemens Schwaighofer
07fbd13213 Setup npm with eslint 2025-02-13 18:24:30 +09:00
Clemens Schwaighofer
44b825310a Add ACL level number to unit detail 2025-02-07 19:06:35 +09:00
Clemens Schwaighofer
2c234ccef6 On config errors do not exit but throw exception 2025-01-29 09:57:58 +09:00
Clemens Schwaighofer
b493b3c4fd Remove debug message 2025-01-20 20:27:34 +09:00
Clemens Schwaighofer
e7dd96b5d9 Further fixes for PHP 8.4 2025-01-20 20:27:03 +09:00
Clemens Schwaighofer
bcde36ac17 DB IO Cache reset should not be an error
If the query is not found, do not throw an error, just show a warning
2025-01-20 10:45:31 +09:00
Clemens Schwaighofer
8bde34ec7d Fix bug in DB IO prepared statement with INSERT and auto RETURNING add
INSERT will get a RETURNING added automatically if it has a primary key
This was not checked when query was compared for prepared statements.

Also added a prepared statement status checker
2025-01-17 17:52:41 +09:00
Clemens Schwaighofer
a345d71306 De-depricate the ACL Login loginCheckEditAccessId method
This is still used a lot, and there is no reason to deprecate it so early.

First all the other logic should be brought in to make this an easy
conversion.
2025-01-17 14:43:13 +09:00
Clemens Schwaighofer
0ff6294faa Fix ACL Login cuid <-> id pk lookups
Used the wrong SESSION var for lookup
2025-01-17 14:34:41 +09:00
Clemens Schwaighofer
757d7ae01d ACL Login fixes for legacy id lookups
add an edit access id lookup to cuid

Fix unit_cuid not initialized, only old unit_id
2025-01-17 12:48:46 +09:00
Clemens Schwaighofer
4e78b21c67 phpstan fix for fegetcsv param $length 2025-01-17 09:59:39 +09:00
Clemens Schwaighofer
d7e6434808 New DeprecatedHelper namespace
For temporary wrapper functions for deprecated calls that need this

PHP 8.4 fputcsv/fgetcsv/str_getcsv encoding default change deprecated warning

Note this does not cover the SqlFileInfo class as this is not used in our code
2025-01-17 09:58:02 +09:00
Clemens Schwaighofer
443cc2751d Update Logging file name change unit tests 2025-01-17 09:33:05 +09:00
Clemens Schwaighofer
cf6500b55a Logging class change to "." for block separator
Blocks for info are now separated with "." and not "_" to make it visual more easy to see
2025-01-17 09:08:13 +09:00
Clemens Schwaighofer
09c2ec653f ACL Login set deprecated edit user id too
We need that for some old calls in old projects
2025-01-16 14:49:15 +09:00
Clemens Schwaighofer
545279b9fe First tests with eslint flat layout 2024-10-16 12:17:24 +09:00
45 changed files with 4382 additions and 383 deletions

View File

@@ -1,43 +0,0 @@
module.exports = {
'env': {
'browser': true,
'es6': true,
'commonjs': true,
'jquery': true
},
'extends': 'eslint:recommended',
'parserOptions': {
'ecmaVersion': 6
},
'rules': {
'indent': [
'error',
'tab',
{
'SwitchCase': 1
}
],
'linebreak-style': [
'error',
'unix'
],
'quotes': [
'error',
'single'
],
'semi': [
'error',
'always'
],
'no-console': 'off',
'no-unused-vars': [
'error', {
'vars': 'all',
'args': 'after-used',
'ignoreRestSiblings': false
}
],
// Requires eslint >= v8.14.0
'no-constant-binary-expression': 'error'
}
};

2
.gitignore vendored
View File

@@ -5,3 +5,5 @@ vendor/
tools/
www/composer.lock
www/vendor
**/.env
**/.target

View File

@@ -48,7 +48,7 @@ header("Content-Type: application/json; charset=UTF-8");
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;
exit(1);
}
// if server request type is get set file_get to null -> no body
@@ -57,7 +57,7 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") {
} 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;
exit(1);
}
print buildContent($http_headers, $file_get);

View File

@@ -152,7 +152,6 @@ final class CoreLibsACLLoginTest extends TestCase
// TARGET
define('TARGET', 'test');
// LOGIN DB SCHEMA
// define('LOGIN_DB_SCHEMA', '');
// SHOULD SET
// DEFAULT_ACL_LEVEL (d80)

View File

@@ -926,48 +926,114 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
public function daysIntervalProvider(): array
{
return [
'valid interval /, not named array' => [
'2020/1/1',
'2020/1/30',
false,
[29, 22, 8],
// normal and format tests
'valid interval / not named array' => [
'input_a' => '2020/1/1',
'input_b' => '2020/1/30',
'return_named' => false, // return_named
'include_end_date' => true, // include_end_date
'exclude_start_date' => false, // exclude_start_date
'expected' => [30, 22, 8, false],
],
'valid interval /, named array' => [
'2020/1/1',
'2020/1/30',
true,
['overall' => 29, 'weekday' => 22, 'weekend' => 8],
'valid interval / named array' => [
'input_a' => '2020/1/1',
'input_b' => '2020/1/30',
'return_named' => true,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => ['overall' => 30, 'weekday' => 22, 'weekend' => 8, 'reverse' => false],
],
'valid interval -' => [
'2020-1-1',
'2020-1-30',
false,
[29, 22, 8],
],
'valid interval switched' => [
'2020/1/30',
'2020/1/1',
false,
[28, 0, 0],
'valid interval with "-"' => [
'input_a' => '2020-1-1',
'input_b' => '2020-1-30',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, false],
],
'valid interval with time' => [
'2020/1/1 12:12:12',
'2020/1/30 13:13:13',
false,
[28, 21, 8],
'input_a' => '2020/1/1 12:12:12',
'input_b' => '2020/1/30 13:13:13',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, false],
],
// invalid
'invalid dates' => [
'abc',
'xyz',
false,
[0, 0, 0]
'input_a' => 'abc',
'input_b' => 'xyz',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [0, 0, 0, false]
],
// this test will take a long imte
// this test will take a long time
'out of bound dates' => [
'1900-1-1',
'9999-12-31',
false,
[2958463,2113189,845274],
'input_a' => '1900-1-1',
'input_b' => '9999-12-31',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [2958463, 2113189, 845274, false],
],
// tests for include/exclude
'exclude end date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => false,
'expected' => [29, 21, 8, false],
],
'exclude start date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => true,
'expected' => [29, 21, 8, false],
],
'exclude start and end date' => [
'input_b' => '2020/1/1',
'input_a' => '2020/1/30',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => true,
'expected' => [28, 20, 8, false],
],
// reverse
'reverse: valid interval' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => false,
'expected' => [30, 22, 8, true],
],
'reverse: exclude end date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => false,
'expected' => [29, 21, 8, true],
],
'reverse: exclude start date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => true,
'exclude_start_date' => true,
'expected' => [29, 21, 8, true],
],
'reverse: exclude start and end date' => [
'input_a' => '2020/1/30',
'input_b' => '2020/1/1',
'return_named' => false,
'include_end_date' => false,
'exclude_start_date' => true,
'expected' => [28, 20, 8, true],
],
];
}
@@ -982,20 +1048,52 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
*
* @param string $input_a
* @param string $input_b
* @param bool $flag
* @param array $expected
* @param bool $return_named
* @param array $expected
* @return void
*/
public function testCalcDaysInterval(
string $input_a,
string $input_b,
bool $flag,
bool $return_named,
bool $include_end_date,
bool $exclude_start_date,
$expected
): void {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysInterval($input_a, $input_b, $flag)
\CoreLibs\Combined\DateTime::calcDaysInterval(
$input_a,
$input_b,
return_named:$return_named,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysInterval'
);
if ($return_named) {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysIntervalNamedIndex(
$input_a,
$input_b,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysIntervalNamedIndex'
);
} else {
$this->assertEquals(
$expected,
\CoreLibs\Combined\DateTime::calcDaysIntervalNumIndex(
$input_a,
$input_b,
include_end_date:$include_end_date,
exclude_start_date:$exclude_start_date
),
'call calcDaysIntervalNamedIndex'
);
}
}
/**
@@ -1187,7 +1285,38 @@ final class CoreLibsCombinedDateTimeTest extends TestCase
'2023-07-03',
'2023-07-27',
true
]
],
// reverse
'reverse: no weekend' => [
'2023-07-04',
'2023-07-03',
false
],
'reverse: start weekend sat' => [
'2023-07-04',
'2023-07-01',
true
],
'reverse: start weekend sun' => [
'2023-07-04',
'2023-07-02',
true
],
'reverse: end weekend sat' => [
'2023-07-08',
'2023-07-03',
true
],
'reverse: end weekend sun' => [
'2023-07-09',
'2023-07-03',
true
],
'reverse: long period > 6 days' => [
'2023-07-27',
'2023-07-03',
true
],
];
}

View File

@@ -40,7 +40,7 @@ final class CoreLibsConvertByteTest extends TestCase
4 => '1.00 KB',
5 => '1.02KiB',
],
'invalud string number' => [
'invalid string number' => [
0 => '1024 MB',
1 => '1024 MB',
2 => '1024 MB',

View File

@@ -3692,7 +3692,7 @@ final class CoreLibsDBIOTest extends TestCase
*
* @return array
*/
public function preparedProviderValue(): array
public function providerDbGetPrepareCursorValue(): array
{
// 1: query (can be empty for do not set)
// 2: stm name
@@ -3736,7 +3736,7 @@ final class CoreLibsDBIOTest extends TestCase
* test return prepare cursor errors
*
* @covers ::dbGetPrepareCursorValue
* @dataProvider preparedProviderValue
* @dataProvider providerDbGetPrepareCursorValue
* @testdox prepared query $stm_name with $key expect error id $error_id [$_dataName]
*
* @param string $query
@@ -3769,6 +3769,94 @@ final class CoreLibsDBIOTest extends TestCase
);
}
/**
* Undocumented function
*
* @return array
*/
public function providerDbPreparedCursorStatus(): array
{
return [
'empty statement pararm' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_a',
'check_stm_name' => '',
'check_query' => '',
'expected' => false
],
'different stm_name' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_b',
'check_stm_name' => 'other_name',
'check_query' => '',
'expected' => 0
],
'same stm_name' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_c',
'check_stm_name' => 'test_stm_c',
'check_query' => '',
'expected' => 1
],
'same stm_name and query' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_d',
'check_stm_name' => 'test_stm_d',
'check_query' => 'SELECT row_int, uid FROM table_with_primary_key',
'expected' => 2
],
'same stm_name and different query' => [
'query' => 'SELECT row_int, uid FROM table_with_primary_key',
'stm_name' => 'test_stm_e',
'check_stm_name' => 'test_stm_e',
'check_query' => 'SELECT row_int, uid, row_int FROM table_with_primary_key',
'expected' => 1
],
'insert query test' => [
'query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)',
'stm_name' => 'test_stm_f',
'check_stm_name' => 'test_stm_f',
'check_query' => 'INSERT INTO table_with_primary_key (row_int, uid) VALUES ($1, $2)',
'expected' => 2
]
];
}
/**
* test cursor status for prepared statement
*
* @covers ::dbPreparedCursorStatus
* @dataProvider providerDbPreparedCursorStatus
* @testdox Check prepared $stm_name ($check_stm_name) status is $expected [$_dataName]
*
* @param string $query
* @param string $stm_name
* @param string $check_stm_name
* @param string $check_query
* @param bool|int $expected
* @return void
*/
public function testDbPreparedCursorStatus(
string $query,
string $stm_name,
string $check_stm_name,
string $check_query,
bool|int $expected
): void {
$db = new \CoreLibs\DB\IO(
self::$db_config['valid'],
self::$log
);
$db->dbPrepare($stm_name, $query);
// $db->dbExecute($stm_name);
$this->assertEquals(
$expected,
$db->dbPreparedCursorStatus($check_stm_name, $check_query),
'check prepared stement cursor status'
);
unset($db);
}
// - schema set/get tests
// dbGetSchema, dbSetSchema

View File

@@ -395,7 +395,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
}
$per_run_id = $log->getLogUniqueId();
$this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
"/^\d{4}-\d{2}-\d{2}_\d{6}\.U_[a-z0-9]{8}$/",
$per_run_id,
'assert per log run id 1st'
);
@@ -403,7 +403,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$log->setLogUniqueId(true);
$per_run_id_2nd = $log->getLogUniqueId();
$this->assertMatchesRegularExpression(
"/^\d{4}-\d{2}-\d{2}_\d{6}_U_[a-z0-9]{8}$/",
"/^\d{4}-\d{2}-\d{2}_\d{6}\.U_[a-z0-9]{8}$/",
$per_run_id_2nd,
'assert per log run id 2nd'
);
@@ -824,13 +824,13 @@ final class CoreLibsLoggingLoggingTest extends TestCase
$this->assertTrue($log_ok, 'assert ::log (debug) OK');
$this->assertEquals(
$log->getLogFile(),
$log->getLogFileId() . '_DEBUG.log'
$log->getLogFileId() . '.DEBUG.log'
);
$log_ok = $log->log(Level::Info, 'INFO', group_id: 'GROUP_ID', prefix: 'PREFIX:');
$this->assertTrue($log_ok, 'assert ::log (info) OK');
$this->assertEquals(
$log->getLogFile(),
$log->getLogFileId() . '_INFO.log'
$log->getLogFileId() . '.INFO.log'
);
}

View File

@@ -969,44 +969,76 @@ final class CoreLibsUrlRequestsCurlTest extends TestCase
"query" => ["foo-get" => "bar"]
]);
$this->assertEquals("200", $response["code"], "multi call: get response code not matching");
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_FIRST_CALL":"get","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"GET",'
. '"PARAMS":{"foo-get":"bar"},"BODY":null}',
$response['content'],
'multi call: get content not matching'
);
if (PHP_VERSION_ID >= 80400) {
$this->assertEquals(
'{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",'
. '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1","HTTP_FIRST_CALL":"get",'
. '"HTTP_ACCEPT":"*\/*"},"REQUEST_TYPE":"GET","PARAMS":{"foo-get":"bar"},"BODY":null}',
$response['content'],
'multi call: get content not matching'
);
} else {
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_FIRST_CALL":"get","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"GET",'
. '"PARAMS":{"foo-get":"bar"},"BODY":null}',
$response['content'],
'multi call: get content not matching'
);
}
// post
$response = $curl->post($this->url_basic, [
"headers" => ["second-call" => "post"],
"body" => ["foo-post" => "baz"]
]);
$this->assertEquals("200", $response["code"], "multi call: post response code not matching");
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"POST",'
. '"PARAMS":[],"BODY":{"foo-post":"baz"}}',
$response['content'],
'multi call: post content not matching'
);
if (PHP_VERSION_ID >= 80400) {
$this->assertEquals(
'{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",'
. '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*"},'
. '"REQUEST_TYPE":"POST","PARAMS":[],"BODY":{"foo-post":"baz"}}',
$response['content'],
'multi call: post content not matching'
);
} else {
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_SECOND_CALL":"post","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"POST",'
. '"PARAMS":[],"BODY":{"foo-post":"baz"}}',
$response['content'],
'multi call: post content not matching'
);
}
// delete
$response = $curl->delete($this->url_basic, [
"headers" => ["third-call" => "delete"],
]);
$this->assertEquals("200", $response["code"], "multi call: delete response code not matching");
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"DELETE",'
. '"PARAMS":[],"BODY":[]}',
$response['content'],
'multi call: delete content not matching'
);
if (PHP_VERSION_ID >= 80400) {
$this->assertEquals(
'{"HEADERS":{"HTTP_HOST":"soba.egplusww.jp",'
. '"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*"},'
. '"REQUEST_TYPE":"DELETE","PARAMS":[],"BODY":[]}',
$response['content'],
'multi call: delete content not matching'
);
} else {
$this->assertEquals(
'{"HEADERS":{"HTTP_USER_AGENT":"CoreLibsUrlRequestCurl\/1",'
. '"HTTP_THIRD_CALL":"delete","HTTP_ACCEPT":"*\/*",'
. '"HTTP_HOST":"soba.egplusww.jp"},'
. '"REQUEST_TYPE":"DELETE",'
. '"PARAMS":[],"BODY":[]}',
$response['content'],
'multi call: delete content not matching'
);
}
}
// MARK: auth header set via config

View File

@@ -114,3 +114,11 @@ Add `.libs` to the master .gitingore
### Update phpunit
On a version update the old phpunit folder in .libs has to be removed and the new version extracted again
## Javascript
The original edit.js javascript functions are now in utils.js or utils.min.js.
The development for thos files is located in a different repository
https://[service]/CodeBlocks/javascript-utils

59
eslint.config.mjs Normal file
View File

@@ -0,0 +1,59 @@
import globals from 'globals';
import pluginJs from '@eslint/js';
/*
module.exports = {
// in globals block
'extends': 'eslint:recommended',
'parserOptions': {
'ecmaVersion': 6
},
// rules copied
};
*/
/** @type {import('eslint').Linter.Config[]} */
export default [
{languageOptions: {
globals: {
...globals.browser,
...globals.jquery
}
}},
pluginJs.configs.recommended,
{
'rules': {
'indent': [
'error',
'tab',
{
'SwitchCase': 1
}
],
'linebreak-style': [
'error',
'unix'
],
// 'quotes': [
// 'error',
// 'single'
// ],
'semi': [
'error',
'always'
],
'no-console': 'off',
'no-unused-vars': [
'error', {
'vars': 'all',
'args': 'after-used',
'ignoreRestSiblings': false
}
],
// Requires eslint >= v8.14.0
'no-constant-binary-expression': 'error'
}
}
];
// __END__

View File

@@ -1,9 +1,11 @@
// https://www.typescriptlang.org/tsconfig/#compilerOptions
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
"target": "ES2020",
"jsx": "react",
"checkJs": true,
"allowImportingTsExtensions": true,
"strictNullChecks": true,
"strictFunctionTypes": true

1567
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
package.json Normal file
View File

@@ -0,0 +1,17 @@
{
"name": "core-libraries",
"version": "9.26.8",
"main": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Clemens Schwaighofer",
"license": "",
"description": "Core Libraries",
"devDependencies": {
"@eslint/js": "^9.20.0",
"esbuild": "^0.25.0",
"eslint": "^9.20.1",
"globals": "^15.15.0"
}
}

View File

@@ -10,5 +10,6 @@ $_SERVER['HTTP_HOST'] = 'soba.tokyo.tequila.jp';
define('BASE_NAME', '');
define('SITE_DOMAIN', '');
define('HOST_NAME', 'soba.tokyo.tequila.jp');
define('DEFAULT_ENCODING', 'en_US.UTF-8');
// __END__

View File

@@ -52,7 +52,7 @@ header("Content-Type: application/json; charset=UTF-8");
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;
exit(1);
}
// if server request type is get set file_get to null -> no body
@@ -61,7 +61,7 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") {
} 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;
exit(1);
}
// str_replace('\"', '"', trim($file_get, '"'));

View File

@@ -268,7 +268,9 @@ foreach ($compare_datetimes as $compare_datetime) {
print "COMPAREDATE: $compare_datetime[0] = $compare_datetime[1]: "
. (string)DateTime::compareDateTime($compare_datetime[0], $compare_datetime[1]) . "<br>";
}
print "<hr>";
print "<h2>calcDaysInterval</h2>";
$compare_dates = [
[ '2021-05-01', '2021-05-10', ],
[ '2021-05-10', '2021-05-01', ],
@@ -279,9 +281,21 @@ foreach ($compare_dates as $compare_date) {
print "CALCDAYSINTERVAL: $compare_date[0] = $compare_date[1]: "
. DgS::printAr(DateTime::calcDaysInterval($compare_date[0], $compare_date[1])) . "<br>";
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 "<h2>setWeekdayNameFromIsoDow</h2>";
// test date conversion
$dow = 2;
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],long;invalid: " . DateTime::setWeekdayNameFromDate($date, true) . "<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>";
@@ -460,7 +473,10 @@ function intervalStringFormatDeprecated(
// print "-> V: $value | $part, $time_name | I: " . is_int($value) . " | F: " . is_float($value)
// . " | " . ($value != 0 ? 'Not zero' : 'ZERO') . "<br>";
// var_dump($skip_last_zero);
if ($value != 0 || $skip_zero === false || $skip_last_zero === false) {
if (
is_numeric($value) &&
($value != 0 || $skip_zero === false || $skip_last_zero === false)
) {
if ($part == 'f') {
if ($truncate_nanoseconds === true) {
$value = round($value, 3);

View File

@@ -76,41 +76,41 @@ $db->dbResetEncoding();
// empty calls, none of the below should fail
//
$db->dbGetCursor();
$foo = $db->dbGetCursor();
//
$db->dbGetCursorExt();
$foo = $db->dbGetCursorExt();
//
$db->dbGetCursorPos('SELECT foo', ['bar']);
$foo = $db->dbGetCursorPos('SELECT foo', ['bar']);
//
$db->dbGetCursorNumRows('SELECT foo', ['bar']);
$foo = $db->dbGetCursorNumRows('SELECT foo', ['bar']);
//
$db->dbGetInsertPKName();
$foo = $db->dbGetInsertPKName();
//
$db->dbGetInsertPK();
$foo = $db->dbGetInsertPK();
//
$db->dbGetReturningExt();
$db->dbGetReturningExt('foo');
$db->dbGetReturningExt('foo', 0);
$db->dbGetReturningExt(pos:0);
$foo = $db->dbGetReturningExt();
$foo = $db->dbGetReturningExt('foo');
$foo = $db->dbGetReturningExt('foo', 0);
$foo = $db->dbGetReturningExt(pos:0);
//
$db->dbGetReturningArray();
$foo = $db->dbGetReturningArray();
//
$db->dbGetNumRows();
$foo = $db->dbGetNumRows();
//
$db->dbGetNumFields();
$foo = $db->dbGetNumFields();
//
$db->dbGetFieldNames();
$foo = $db->dbGetFieldNames();
//
$db->dbGetFieldTypes();
$foo = $db->dbGetFieldTypes();
//
$db->dbGetFieldNameTypes();
$foo = $db->dbGetFieldNameTypes();
//
$db->dbGetFieldName(0);
$foo = $db->dbGetFieldName(0);
//
$db->dbGetFieldType(0);
$db->dbGetFieldType('foo');
$foo = $db->dbGetFieldType(0);
$foo = $db->dbGetFieldType('foo');
//
$db->dbGetPrepareCursorValue('foo', 'bar');
$foo = $db->dbGetPrepareCursorValue('foo', 'bar');
// TEST CACHE READS
@@ -707,6 +707,17 @@ if (
} else {
print "[PGB] [3] pgb_sel_test_foo prepare OK<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 write class test

View File

@@ -0,0 +1,107 @@
<?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 ($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

@@ -117,7 +117,7 @@ if (isset($login->loginGetAcl()['unit'])) {
if ($login->loginCheckEditAccessCuid($edit_access_cuid)) {
print "Set new:" . $edit_access_cuid . "<br>";
} else {
print "Load default unit id: " . $login->loginGetAcl()['unit_id'] . "<br>";
print "Load default unit id: " . $login->loginGetAcl()['unit_cuid'] . "<br>";
}
} else {
print "Something went wrong with the login<br>";
@@ -140,4 +140,17 @@ $login->writeLog(
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>";
print "</body></html>";

View File

@@ -141,6 +141,7 @@ $test_files = [
'class_test.error_msg.php' => 'Class Test: ERROR MSG',
'class_test.url-requests.curl.php' => 'Class Test: URL REQUESTS: CURL',
'subfolder/class_test.config.direct.php' => 'Class Test: CONFIG DIRECT SUB',
'class_test.deprecated.helper.php' => 'Class Test: DEPRECATED HELPERS',
];
asort($test_files);

View File

@@ -28,8 +28,6 @@ $log = new CoreLibs\Logging\Logging([
$_phpv = new CoreLibs\Check\PhpVersion();
$phpv_class = 'CoreLibs\Check\PhpVersion';
// define a list of from to color sets for conversion test
$PAGE_NAME = 'TEST CLASS: PHP VERSION';
print "<!DOCTYPE html>";
print "<html><head><title>" . $PAGE_NAME . "</title></head>";

View File

@@ -86,8 +86,10 @@ if (!isset($_SESSION['counter'])) {
$_SESSION['counter']++;
print "[READ] A " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>";
$_SESSION[$var] = $value;
/** @phpstan-ignore-next-line nullCoalesce.offset */
print "[READ] B " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "<br>";
print "[READ] Confirm " . $var . " is " . $value . ": "
/** @phpstan-ignore-next-line equal.alwaysTrue, nullCoalesce.offset */
. (($_SESSION[$var] ?? '') == $value ? 'Matching' : 'Not matching') . "<br>";
// test set wrappers methods

View File

@@ -1,7 +1,9 @@
/* general edit javascript */
/* jquery version */
/*
general edit javascript
jquery version
*/
/* jshint esversion: 11 */
/** @deprecated Do not use this anymore, use utils.js or utils.min.js */
/* global i18n */
@@ -18,11 +20,28 @@ if (!DEBUG) {
var GL_OB_S = 100;
var GL_OB_BASE = 100;
/**
* Gets html element or throws an error
* @param {string} el_id Element ID to get
* @returns {HTMLElement}
* @throws Error
* @deprecated use utils.js
*/
function loadEl(el_id)
{
let el = document.getElementById(el_id);
if (el === null) {
throw new Error('Cannot find: ' + el_id);
}
return el;
}
/**
* opens a popup window with winName and given features (string)
* @param {String} theURL the url
* @param {String} winName window name
* @param {Object} features popup features
* @deprecated use utils.js
*/
function pop(theURL, winName, features) // eslint-disable-line no-unused-vars
{
@@ -33,6 +52,7 @@ function pop(theURL, winName, features) // eslint-disable-line no-unused-vars
/**
* automatically resize a text area based on the amount of lines in it
* @param {string} ta_id element id
* @deprecated use utils.js
*/
function expandTA(ta_id) // eslint-disable-line no-unused-vars
{
@@ -58,6 +78,7 @@ function expandTA(ta_id) // eslint-disable-line no-unused-vars
/**
* wrapper to get the real window size for the current browser window
* @return {Object} object with width/height
* @deprecated use utils.js
*/
function getWindowSize()
{
@@ -73,6 +94,7 @@ function getWindowSize()
/**
* wrapper to get the correct scroll offset
* @return {Object} object with x/y px
* @deprecated use utils.js
*/
function getScrollOffset()
{
@@ -88,6 +110,7 @@ function getScrollOffset()
/**
* wrapper to get the correct scroll offset for opener page (from popup)
* @return {Object} object with x/y px
* @deprecated use utils.js
*/
function getScrollOffsetOpener() // eslint-disable-line no-unused-vars
{
@@ -105,6 +128,7 @@ function getScrollOffsetOpener() // eslint-disable-line no-unused-vars
* @param {String} id element to center
* @param {Boolean} left if true centers to the middle from the left
* @param {Boolean} top if true centers to the middle from the top
* @deprecated use utils.js
*/
function setCenter(id, left, top)
{
@@ -142,6 +166,7 @@ function setCenter(id, left, top)
* @param {Number} [offset=0] offset from top, default is 0 (px)
* @param {Number} [duration=500] animation time, default 500ms
* @param {String} [base='body,html'] base element for offset scroll
* @deprecated use utils.js
*/
function goToPos(element, offset = 0, duration = 500, base = 'body,html') // eslint-disable-line no-unused-vars
{
@@ -156,11 +181,25 @@ function goToPos(element, offset = 0, duration = 500, base = 'body,html') // esl
}
}
/**
* go to element, scroll
* non jquery
* @param {string} target
* @deprecated use utils.js
*/
function goTo(target) // eslint-disable-line no-unused-vars
{
loadEl(target).scrollIntoView({
behavior: 'smooth'
});
}
/**
* uses the i18n object created in the translation template
* that is filled from gettext in PHP
* @param {String} string text to translate
* @return {String} translated text (based on PHP selected language)
* @deprecated use utils.js
*/
function __(string)
{
@@ -177,37 +216,70 @@ function __(string)
* First, checks if it isn't implemented yet.
* @param {String} String.prototype.format string with elements to be replaced
* @return {String} Formated string
* @deprecated use utils.js
*/
if (!String.prototype.format) {
String.prototype.format = function()
{
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number)
{
return typeof args[number] != 'undefined' ?
args[number] :
match
;
});
console.error('[DEPRECATED] use formatString');
return formatString(this, arguments);
};
}
/**
* simple sprintf formater for replace
* usage: "{0} is cool, {1} is not".format("Alpha", "Beta");
* First, checks if it isn't implemented yet.
* @param {String} string String with {..} entries
* @param {...any} args List of replacement
* @returns {String} Escaped string
* @deprecated use utils.js
*/
function formatString(string, ...args)
{
return string.replace(/{(\d+)}/g, function(match, number)
{
return typeof args[number] != 'undefined' ?
args[number] :
match
;
});
}
/**
* round to digits (float)
* @param {Number} Number.prototype.round Float type number to round
* @param {Number} prec Precision to round to
* @return {Float} Rounded number
* @deprecated use utils.js
*/
if (Number.prototype.round) {
Number.prototype.round = function (prec) {
console.error('[DEPRECATED] use roundPrecision');
return roundPrecision(this, prec);
};
}
/**
* round to digits (float)
* @param {Float} Number.prototype.round Float type number to round
* @param {Number} prec Precision to round to
* @return {Float} Rounded number
* @param {Number} number Float type number to round
* @param {Number} precision Precision to round to
* @return {Number} Rounded number
* @deprecated use utils.js
*/
if (Number.prototype.round) {
Number.prototype.round = function (prec) {
return Math.round(this * Math.pow(10, prec)) / Math.pow(10, prec);
};
function roundPrecision(number, precision)
{
if (!isNaN(number) || !isNaN(precision)) {
return number;
}
return Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);
}
/**
* formats flat number 123456 to 123,456
* @param {Number} x number to be formated
* @return {String} formatted with , in thousands
* @deprecated use utils.js
*/
function numberWithCommas(x) // eslint-disable-line no-unused-vars
{
@@ -220,6 +292,7 @@ function numberWithCommas(x) // eslint-disable-line no-unused-vars
* converts line breaks to br
* @param {String} string any string
* @return {String} string with <br>
* @deprecated use utils.js
*/
function convertLBtoBR(string) // eslint-disable-line no-unused-vars
{
@@ -228,51 +301,78 @@ function convertLBtoBR(string) // eslint-disable-line no-unused-vars
/**
* escape HTML string
* @param {String} !String.prototype.escapeHTML HTML data string to be escaped
* @return {String} escaped string
* @param {String} String.prototype.escapeHTML HTML data string to be escaped
* @return {String} escaped string
* @deprecated use utils.js
*/
if (!String.prototype.escapeHTML) {
String.prototype.escapeHTML = function() {
return this.replace(/[&<>"'/]/g, function (s) {
var entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;',
'/': '&#x2F;'
};
return entityMap[s];
});
console.error('[DEPRECATED] use escapeHtml');
return escapeHtml(this);
};
}
/**
* unescape a HTML encoded string
* @param {String} !String.prototype.unescapeHTML data with escaped entries
* @return {String} HTML formated string
* @param {String} String.prototype.unescapeHTML data with escaped entries
* @return {String} HTML formated string
* @deprecated use utils.js
*/
if (!String.prototype.unescapeHTML) {
String.prototype.unescapeHTML = function() {
return this.replace(/&[#\w]+;/g, function (s) {
var entityMap = {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#39;': '\'',
'&#x2F;': '/'
};
return entityMap[s];
});
console.error('[DEPRECATED] use unescapeHtml');
return unescapeHtml(this);
};
}
/**
* Escapes HTML in string
* @param {String} string Text to escape HTML in
* @returns {String}
* @deprecated use utils.js
*/
function escapeHtml(string)
{
return string.replace(/[&<>"'/]/g, function (s) {
var entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;',
'/': '&#x2F;'
};
return entityMap[s];
});
}
/**
* Unescape a HTML encoded string
* @param {String} string Text to unescape HTML in
* @returns {String}
* @deprecated use utils.js
*/
function unescapeHtml(string)
{
return string.replace(/&[#\w]+;/g, function (s) {
var entityMap = {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#39;': '\'',
'&#x2F;': '/'
};
return entityMap[s];
});
}
/**
* returns current timestamp (unix timestamp)
* @return {Number} timestamp (in milliseconds)
* @deprecated use utils.js
*/
function getTimestamp() // eslint-disable-line no-unused-vars
{
@@ -285,6 +385,7 @@ function getTimestamp() // eslint-disable-line no-unused-vars
* i.e. 0-255 -> '00'-'ff'
* @param {Number} dec decimal string
* @return {String} hex encdoded number
* @deprecated use utils.js
*/
function dec2hex(dec)
{
@@ -296,6 +397,7 @@ function dec2hex(dec)
* only works on mondern browsers
* @param {Number} len length of unique id string
* @return {String} random string in length of len
* @deprecated use utils.js
*/
function generateId(len) // eslint-disable-line no-unused-vars
{
@@ -309,6 +411,7 @@ function generateId(len) // eslint-disable-line no-unused-vars
* works on all browsers
* after many runs it will create duplicates
* @return {String} not true random string
* @deprecated use utils.js
*/
function randomIdF() // eslint-disable-line no-unused-vars
{
@@ -322,6 +425,7 @@ function randomIdF() // eslint-disable-line no-unused-vars
* @param {Number} min minimum int number inclusive
* @param {Number} max maximumg int number inclusive
* @return {Number} Random number
* @deprecated use utils.js
*/
function getRandomIntInclusive(min, max) // eslint-disable-line no-unused-vars
{
@@ -335,6 +439,7 @@ function getRandomIntInclusive(min, max) // eslint-disable-line no-unused-vars
* check if name is a function
* @param {string} name Name of function to check if exists
* @return {Boolean} true/false
* @deprecated use utils.js
*/
function isFunction(name) // eslint-disable-line no-unused-vars
{
@@ -354,6 +459,7 @@ function isFunction(name) // eslint-disable-line no-unused-vars
* @param {mixed} context context (window or first namespace)
* hidden next are all the arguments
* @return {mixed} Return values from functon
* @deprecated use utils.js
*/
function executeFunctionByName(functionName, context /*, args */) // eslint-disable-line no-unused-vars
{
@@ -370,6 +476,7 @@ function executeFunctionByName(functionName, context /*, args */) // eslint-disa
* checks if a variable is an object
* @param {Mixed} val possible object
* @return {Boolean} true/false if it is an object or not
* @deprecated use utils.js
*/
function isObject(val)
{
@@ -383,6 +490,7 @@ function isObject(val)
* get the length of an object (entries)
* @param {Object} object object to check
* @return {Number} number of entry
* @deprecated use utils.js
*/
function getObjectCount(object)
{
@@ -394,6 +502,7 @@ function getObjectCount(object)
* @param {String} key key name
* @param {Object} object object to search key in
* @return {Boolean} true/false if key exists in object
* @deprecated use utils.js
*/
function keyInObject(key, object)
{
@@ -402,9 +511,10 @@ function keyInObject(key, object)
/**
* returns matching key of value
* @param {Object} obj object to search value in
* @param {Mixed} value any value (String, Number, etc)
* @return {String} the key found for the first matching value
* @param {Object} object object to search value in
* @param {Mixed} value any value (String, Number, etc)
* @return {String} the key found for the first matching value
* @deprecated use utils.js
*/
function getKeyByValue(object, value) // eslint-disable-line no-unused-vars
{
@@ -416,9 +526,10 @@ function getKeyByValue(object, value) // eslint-disable-line no-unused-vars
/**
* returns true if value is found in object with a key
* @param {Object} obj object to search value in
* @param {Mixed} value any value (String, Number, etc)
* @return {Boolean} true on value found, false on not found
* @param {Object} object object to search value in
* @param {Mixed} value any value (String, Number, etc)
* @return {Boolean} true on value found, false on not found
* @deprecated use utils.js
*/
function valueInObject(object, value) // eslint-disable-line no-unused-vars
{
@@ -434,6 +545,7 @@ function valueInObject(object, value) // eslint-disable-line no-unused-vars
* or if JSON.parse(JSON.stringify(obj)) is failing
* @param {Object} inObject Object to copy
* @return {Object} Copied Object
* @deprecated use utils.js
*/
function deepCopyFunction(inObject)
{
@@ -457,6 +569,7 @@ function deepCopyFunction(inObject)
* checks if a DOM element actually exists
* @param {String} id Element id to check for
* @return {Boolean} true if element exists, false on failure
* @deprecated use utils.js
*/
function exists(id)
{
@@ -468,6 +581,7 @@ function exists(id)
* currently precision is fixed, if dynamic needs check for max/min precision
* @param {Number} bytes bytes in int
* @return {String} string in GB/MB/KB
* @deprecated use utils.js
*/
function formatBytes(bytes) // eslint-disable-line no-unused-vars
{
@@ -484,6 +598,7 @@ function formatBytes(bytes) // eslint-disable-line no-unused-vars
* like formatBytes, but returns bytes for <1KB and not 0.n KB
* @param {Number} bytes bytes in int
* @return {String} string in GB/MB/KB
* @deprecated use utils.js
*/
function formatBytesLong(bytes) // eslint-disable-line no-unused-vars
{
@@ -496,6 +611,7 @@ function formatBytesLong(bytes) // eslint-disable-line no-unused-vars
* Convert a string with B/K/M/etc into a byte number
* @param {String|Number} bytes Any string with B/K/M/etc
* @return {String|Number} A byte number, or original string as is
* @deprecated use utils.js
*/
function stringByteFormat(bytes) // eslint-disable-line no-unused-vars
{
@@ -526,6 +642,7 @@ function stringByteFormat(bytes) // eslint-disable-line no-unused-vars
/**
* prints out error messages based on data available from the browser
* @param {Object} err error from try/catch block
* @deprecated use utils.js
*/
function errorCatch(err)
{
@@ -533,22 +650,20 @@ function errorCatch(err)
if (err.stack) {
// only FF
if (err.lineNumber) {
console.log('ERROR[%s:%s] %s', err.name, err.lineNumber, err.message);
console.error('ERROR[%s:%s] ', err.name, err.lineNumber, err);
} else if (err.line) {
// only Safari
console.log('ERROR[%s:%s] %s', err.name, err.line, err.message);
console.error('ERROR[%s:%s] ', err.name, err.line, err);
} else {
console.log('ERROR[%s] %s', err.name, err.message);
console.error('ERROR[%s] ', err.name, err);
}
// stack trace
console.log('ERROR[stack] %s', err.stack);
} else if (err.number) {
// IE
console.log('ERROR[%s:%s] %s', err.name, err.number, err.message);
console.log('ERROR[description] %s', err.description);
console.error('ERROR[%s:%s] %s', err.name, err.number, err.message);
console.error('ERROR[description] %s', err.description);
} else {
// the rest
console.log('ERROR[%s] %s', err.name, err.message);
console.error('ERROR[%s] %s', err.name, err.message);
}
}
@@ -571,6 +686,7 @@ function errorCatch(err)
* @param {String} loc location name for action indicator
* default empty. for console.log
* @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block
* @deprecated use utils.js
*/
function actionIndicator(loc, overlay = true) // eslint-disable-line no-unused-vars
{
@@ -587,6 +703,7 @@ function actionIndicator(loc, overlay = true) // eslint-disable-line no-unused-v
* @param {String} loc location name for action indicator
* default empty. for console.log
* @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block
* @deprecated use utils.js
*/
function actionIndicatorShow(loc, overlay = true)
{
@@ -609,6 +726,7 @@ function actionIndicatorShow(loc, overlay = true)
* @param {String} loc location name for action indicator
* default empty. for console.log
* @param {Boolean} [overlay=true] override the auto hide/show over the overlay div block
* @deprecated use utils.js
*/
function actionIndicatorHide(loc, overlay = true)
{
@@ -621,6 +739,7 @@ function actionIndicatorHide(loc, overlay = true)
/**
* shows the overlay box or if already visible, bumps the zIndex to 100
* @deprecated use utils.js
*/
function overlayBoxShow()
{
@@ -635,6 +754,7 @@ function overlayBoxShow()
/**
* hides the overlay box or if zIndex is 100 bumps it down to previous level
* @deprecated use utils.js
*/
function overlayBoxHide()
{
@@ -648,6 +768,7 @@ function overlayBoxHide()
/**
* position the overlay block box and shows it
* @deprecated use utils.js
*/
function setOverlayBox() // eslint-disable-line no-unused-vars
{
@@ -658,6 +779,7 @@ function setOverlayBox() // eslint-disable-line no-unused-vars
/**
* opposite of set, always hides overlay box
* @deprecated use utils.js
*/
function hideOverlayBox() // eslint-disable-line no-unused-vars
{
@@ -668,6 +790,7 @@ function hideOverlayBox() // eslint-disable-line no-unused-vars
/**
* the abort call, clears the action box and hides it and the overlay box
* @deprecated use utils.js
*/
function ClearCall() // eslint-disable-line no-unused-vars
{
@@ -689,6 +812,7 @@ function ClearCall() // eslint-disable-line no-unused-vars
* zIndex of 1000
* - indicator is page centered
* @param {String} loc ID string, only used for console log
* @deprecated use utils.js
*/
function showActionIndicator(loc) // eslint-disable-line no-unused-vars
{
@@ -727,6 +851,7 @@ function showActionIndicator(loc) // eslint-disable-line no-unused-vars
* the overlayBox is not hidden but the zIndex
* is set to this value
* @param {String} loc ID string, only used for console log
* @deprecated use utils.js
*/
function hideActionIndicator(loc) // eslint-disable-line no-unused-vars
{
@@ -750,6 +875,7 @@ function hideActionIndicator(loc) // eslint-disable-line no-unused-vars
/**
* checks if overlayBox exists, if not it is
* added as hidden item at the body end
* @deprecated use utils.js
*/
function checkOverlayExists()
{
@@ -767,6 +893,7 @@ function checkOverlayExists()
* if not visible show and set zIndex to 10 (GL_OB_BASE)
* if visible, add +1 to the GL_OB_S variable and
* up zIndex by this value
* @deprecated use utils.js
*/
function showOverlayBoxLayers(el_id) // eslint-disable-line no-unused-vars
{
@@ -799,8 +926,9 @@ function showOverlayBoxLayers(el_id) // eslint-disable-line no-unused-vars
* and set zIndex and GL_OB_S to 0
* else just set zIndex to the new GL_OB_S value
* @param {String} el_id Target to hide layer
* @deprecated use utils.js
*/
function hideOverlayBoxLayers(el_id)
function hideOverlayBoxLayers(el_id='')
{
// console.log('HIDE overlaybox: %s', GL_OB_S);
// remove on layer
@@ -824,6 +952,7 @@ function hideOverlayBoxLayers(el_id)
/**
* only for single action box
* @deprecated use utils.js
*/
function clearCallActionBox() // eslint-disable-line no-unused-vars
{
@@ -841,6 +970,7 @@ function clearCallActionBox() // eslint-disable-line no-unused-vars
* @param {Array} [css=[]] array for css tags
* @param {Object} [options={}] anything else (value, placeholder, OnClick, style)
* @return {Object} created element as an object
* @deprecated use utils.js
*/
function cel(tag, id = '', content = '', css = [], options = {})
{
@@ -861,6 +991,7 @@ function cel(tag, id = '', content = '', css = [], options = {})
* @param {Object} attach the object to be attached
* @param {String} [id=''] optional id, if given search in base for this id and attach there
* @return {Object} "none", technically there is no return needed as it is global attach
* @deprecated use utils.js
*/
function ael(base, attach, id = '')
{
@@ -891,6 +1022,7 @@ function ael(base, attach, id = '')
* @param {Object} base object to where we attach the elements
* @param {...Object} attach attach 1..n: attach directly to the base element those attachments
* @return {Object} "none", technically there is no return needed, global attach
* @deprecated use utils.js
*/
function aelx(base, ...attach)
{
@@ -907,6 +1039,7 @@ function aelx(base, ...attach)
* @param {Object} base object to where we attach the elements
* @param {Array} attach array of objects to attach
* @return {Object} "none", technically there is no return needed, global attach
* @deprecated use utils.js
*/
function aelxar(base, attach) // eslint-disable-line no-unused-vars
{
@@ -921,6 +1054,7 @@ function aelxar(base, attach) // eslint-disable-line no-unused-vars
* resets the sub elements of the base element given
* @param {Object} base cel created element
* @return {Object} returns reset base element
* @deprecated use utils.js
*/
function rel(base) // eslint-disable-line no-unused-vars
{
@@ -933,6 +1067,7 @@ function rel(base) // eslint-disable-line no-unused-vars
* @param {Object} _element element to work one
* @param {String} css style sheet to remove (name)
* @return {Object} returns full element
* @deprecated use utils.js
*/
function rcssel(_element, css)
{
@@ -948,6 +1083,7 @@ function rcssel(_element, css)
* @param {Object} _element element to work on
* @param {String} css style sheet to add (name)
* @return {Object} returns full element
* @deprecated use utils.js
*/
function acssel(_element, css)
{
@@ -965,6 +1101,7 @@ function acssel(_element, css)
* @param {String} rcss style to remove (name)
* @param {String} acss style to add (name)
* @return {Object} returns full element
* @deprecated use utils.js
*/
function scssel(_element, rcss, acss) // eslint-disable-line no-unused-vars
{
@@ -977,6 +1114,7 @@ function scssel(_element, rcss, acss) // eslint-disable-line no-unused-vars
* that can be inserted into the page
* @param {Object} tree object tree with dom element declarations
* @return {String} HTML string that can be used as innerHTML
* @deprecated use utils.js
*/
function phfo(tree)
{
@@ -1083,6 +1221,7 @@ function phfo(tree)
* Is like tree.sub call
* @param {Array} list Array of cel created objects
* @return {String} HTML String
* @deprecated use utils.js
*/
function phfa(list) // eslint-disable-line no-unused-vars
{
@@ -1109,11 +1248,14 @@ function phfa(list) // eslint-disable-line no-unused-vars
* @param {String} [sort=''] if empty as is, else allowed 'keys',
* 'values' all others are ignored
* @return {String} html with build options block
* @deprecated use utils.js
*/
function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '') // eslint-disable-line no-unused-vars
{
// wrapper to new call
return html_options_block(name, data, selected, false, options_only, return_string, sort);
return html_options_block(
name, data, selected, 0, options_only, return_string, sort
);
}
/**
@@ -1134,9 +1276,11 @@ function html_options(name, data, selected = '', options_only = false, return_st
* 'values' all others are ignored
* @param {String} [onchange=''] onchange trigger call, default unset
* @return {String} html with build options block
* @deprecated use utils.js
*/
function html_options_block(name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '', onchange = '')
{
function html_options_block(
name, data, selected = '', multiple = 0, options_only = false, return_string = false, sort = '', onchange = ''
) {
var content = [];
var element_select;
var select_options = {};
@@ -1173,7 +1317,8 @@ function html_options_block(name, data, selected = '', multiple = 0, options_onl
// basic options init
options = {
'label': value,
'value': key
'value': key,
'selected': ''
};
// add selected if matching
if (multiple == 0 && !Array.isArray(selected) && selected == key) {
@@ -1184,7 +1329,7 @@ function html_options_block(name, data, selected = '', multiple = 0, options_onl
options.selected = '';
}
// create the element option
element_option = cel('option', '', value, '', options);
element_option = cel('option', '', value, [], options);
// attach it to the select element
ael(element_select, element_option);
}
@@ -1214,6 +1359,7 @@ function html_options_block(name, data, selected = '', multiple = 0, options_onl
* @param {String} name name/id
* @param {Object} data array of options
* @param {String} [sort=''] if empty as is, else allowed 'keys', 'values'
* @deprecated use utils.js
* all others are ignored
*/
function html_options_refill(name, data, sort = '') // eslint-disable-line no-unused-vars
@@ -1236,7 +1382,7 @@ function html_options_refill(name, data, sort = '') // eslint-disable-line no-un
[].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) {
option_selected = elm.value;
});
document.getElementById(name).innerHTML = '';
loadEl(name).innerHTML = '';
for (const key of data_list) {
value = data[key];
// console.log('add [%s] options: key: %s, value: %s', name, key, value);
@@ -1247,7 +1393,7 @@ function html_options_refill(name, data, sort = '') // eslint-disable-line no-un
if (key == option_selected) {
element_option.selected = true;
}
document.getElementById(name).appendChild(element_option);
loadEl(name).appendChild(element_option);
}
}
}
@@ -1262,6 +1408,7 @@ function html_options_refill(name, data, sort = '') // eslint-disable-line no-un
* @param {String} [return_key=''] if set only returns this key entry
* or empty for none
* @return {Object|String} parameter entry list
* @deprecated use utils.js
*/
function parseQueryString(query = '', return_key = '') // eslint-disable-line no-unused-vars
{
@@ -1311,11 +1458,12 @@ function parseQueryString(query = '', return_key = '') // eslint-disable-line no
* all parameters are returned
* @param {String} [query=''] different query string to parse, if not
* set (default) the current window href is used
* @param {Bool} [single=false] if set to true then only the first found
* @param {Boolean} [single=false] if set to true then only the first found
* will be returned
* @return {Object|Array|String} if search is empty, object, if search is set
* and only one entry, then string, else array
* unless single is true
* @deprecated use utils.js
*/
function getQueryStringParam(search = '', query = '', single = false) // eslint-disable-line no-unused-vars
{
@@ -1323,7 +1471,7 @@ function getQueryStringParam(search = '', query = '', single = false) // eslint-
query = window.location.href;
}
const url = new URL(query);
let param = '';
let param = null;
if (search) {
let _params = url.searchParams.getAll(search);
if (_params.length == 1 || single === true) {
@@ -1353,6 +1501,7 @@ function getQueryStringParam(search = '', query = '', single = false) // eslint-
// *** MASTER logout call
/**
* submits basic data for form logout
* @deprecated use utils.js
*/
function loginLogout() // eslint-disable-line no-unused-vars
{
@@ -1373,6 +1522,7 @@ function loginLogout() // eslint-disable-line no-unused-vars
* @param {String} [header_id='mainHeader'] the target for the main element block
* if not set mainHeader is assumed
* this is the target div for the "loginRow"
* @deprecated use utils.js
*/
function createLoginRow(login_string, header_id = 'mainHeader') // eslint-disable-line no-unused-vars
{
@@ -1408,6 +1558,7 @@ function createLoginRow(login_string, header_id = 'mainHeader') // eslint-disabl
* @param {String} [header_id='mainHeader'] the target for the main element block
* if not set mainHeader is assumed
* this is the target div for the "menuRow"
* @deprecated use utils.js
*/
function createNavMenu(nav_menu, header_id = 'mainHeader') // eslint-disable-line no-unused-vars
{

View File

@@ -1,5 +1,11 @@
/* general edit javascript */
/* prototype version */
/*
general edit javascript
prototype version
*/
/** @deprecated Do not use this anymore, use utils.js */
throw new Error("Prototype Support is deprected, please switch to jquery and utils.js/utils.min.js");
/* jshint esversion: 6 */
@@ -25,7 +31,7 @@ function pop(theURL, winName, features) {
/**
* automatically resize a text area based on the amount of lines in it
* @param {[string} ta_id element id
* @param {string} ta_id element id
*/
function expandTA(ta_id) {
var ta;

View File

@@ -0,0 +1,5 @@
var i18n = {
"Original": "Translated"
};
// __END__

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

@@ -0,0 +1,3 @@
# target can be live, stage, test, dev
# this overrides the SITE set "location" entry
TARGET=

View File

@@ -78,42 +78,11 @@ define('TEMPLATES_C', 'templates_c' . DIRECTORY_SEPARATOR);
// template base
define('TEMPLATES', 'templates' . DIRECTORY_SEPARATOR);
/************* HASH / ACL DEFAULT / ERROR SETTINGS / SMARTY *************/
/************* HASH / ACL DEFAULT *************/
// default hash type
define('DEFAULT_HASH', 'sha256');
// default acl level
define('DEFAULT_ACL_LEVEL', 80);
// SSL host name
// define('SSL_HOST', $_ENV['SSL_HOST'] ?? '');
// error page strictness, Default is 3
// 1: only show error page as the last mesure if really no mid & aid can be loaded and found at all
// 2: if template not found, do not search, show error template
// 3: if default template is not found, show error template, do not fall back to default tree
// 4: very strict, even on normal fixable errors through error
// define('ERROR_STRICT', 3);
// allow page caching in general, set to 'false' if you do debugging or development!
// define('ALLOW_SMARTY_CACHE', false);
// cache life time, in second', default here is 2 days (172800s)
// -1 is never expire cache
// define('SMARTY_CACHE_LIFETIME', -1);
/************* LOGOUT ********************/
// logout target
define('LOGOUT_TARGET', '');
/************* AJAX / ACCESS *************/
// ajax request type
define('AJAX_REQUEST_TYPE', 'POST');
// what AJAX type to use
define('USE_PROTOTYPE', false);
define('USE_SCRIPTACULOUS', false);
define('USE_JQUERY', true);
/************* LAYOUT WIDTHS *************/
define('PAGE_WIDTH', '100%');
define('CONTENT_WIDTH', '100%');
// the default template name
define('MASTER_TEMPLATE_NAME', 'main_body.tpl');
define('DEFAULT_ACL_LEVEL', $ENV['DEFAULT_ACL_LEVEL'] ?? 80);
/************* OVERALL CONTROL NAMES *************/
// BELOW has HAS to be changed
@@ -136,24 +105,15 @@ define('COMPILE_ID', 'COMPILE_' . BASE_NAME . '_' . SERVER_NAME_HASH);
/************* LANGUAGE / ENCODING *******/
// default lang + encoding
define('DEFAULT_LOCALE', 'en_US.UTF-8');
define('DEFAULT_LOCALE', $_ENV['LOCALE'] ?? 'en_US.UTF-8');
// default web page encoding setting
define('DEFAULT_ENCODING', 'UTF-8');
define('DEFAULT_ENCODING', (string)array_pad(explode('.', DEFAULT_LOCALE, 2), 2, 'UTF-8')[1]);
/************* QUEUE TABLE *************/
// if we have a dev/live system
// set_live is a per page/per item
// live_queue is a global queue system
// define('QUEUE', 'live_queue');
/************* DB PATHS (PostgreSQL) *****************/
// schema names, can also be defined per <DB INFO>
define('PUBLIC_SCHEMA', 'public');
define('DEV_SCHEMA', 'public');
define('TEST_SCHEMA', 'public');
define('LIVE_SCHEMA', 'public');
define('GLOBAL_DB_SCHEMA', '');
define('LOGIN_DB_SCHEMA', '');
/************* HOST NAME *****************/
// get the name without the port
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
// set HOST name
define('HOST_NAME', $HOST_NAME);
/************* CORE HOST SETTINGS *****************/
if (file_exists(BASE . CONFIGS . 'config.host.php')) {
@@ -162,6 +122,14 @@ if (file_exists(BASE . CONFIGS . 'config.host.php')) {
if (!isset($SITE_CONFIG)) {
$SITE_CONFIG = [];
}
// BAIL ON MISSING MASTER SITE CONFIG
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
throw new \InvalidArgumentException(
'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator'
);
}
// set target first
define('TARGET', $_ENV['TARGET'] ?? $SITE_CONFIG[HOST_NAME]['location'] ?? 'test');
/************* DB ACCESS *****************/
if (file_exists(BASE . CONFIGS . 'config.db.php')) {
require BASE . CONFIGS . 'config.db.php';
@@ -175,17 +143,6 @@ if (file_exists(BASE . CONFIGS . 'config.path.php')) {
}
/************* MASTER INIT *****************/
// live frontend pages
// ** missing live domains **
// get the name without the port
[$HOST_NAME] = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
// set HOST name
define('HOST_NAME', $HOST_NAME);
// BAIL ON MISSING MASTER SITE CONFIG
if (!isset($SITE_CONFIG[HOST_NAME]['location'])) {
echo 'Missing SITE_CONFIG entry for: "' . HOST_NAME . '". Contact Administrator';
exit;
}
// BAIL ON MISSING DB CONFIG:
// we have either no db selction for this host but have db config entries
// or we have a db selection but no db config as array or empty
@@ -200,8 +157,9 @@ if (
empty($DB_CONFIG[$SITE_CONFIG[HOST_NAME]['db_host']]))
)
) {
echo 'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator';
exit;
throw new \InvalidArgumentException(
'No matching DB config found for: "' . HOST_NAME . '". Contact Administrator'
);
}
// set SSL on
$is_secure = false;
@@ -235,35 +193,31 @@ define('DB_CONFIG', $DB_CONFIG[DB_CONFIG_NAME] ?? [
]);
// because we can't change constant, but we want to for db debug flag
$GLOBALS['DB_CONFIG_SET'] = DB_CONFIG;
// define('DB_CONFIG_TARGET', SITE_CONFIG[$HOST_NAME]['db_host_target']);
// define('DB_CONFIG_OTHER', SITE_CONFIG[$HOST_NAME]['db_host_other']);
// override for login and global schemas
// where the edit* tables are
// define('LOGIN_DB_SCHEMA', PUBLIC_SCHEMA);
// where global tables are that are used by all schemas (eg queue tables for online, etc)
// define('GLOBAL_DB_SCHEMA', PUBLIC_SCHEMA);
// debug settings, site lang, etc
define('TARGET', $SITE_CONFIG[HOST_NAME]['location'] ?? 'test');
define('DEBUG_LEVEL', $SITE_CONFIG[HOST_NAME]['debug_level'] ?? 'debug');
define('SITE_LOCALE', $SITE_CONFIG[HOST_NAME]['site_locale'] ?? DEFAULT_LOCALE);
define('SITE_DOMAIN', str_replace(DIRECTORY_SEPARATOR, '', CONTENT_PATH));
define('SITE_ENCODING', $SITE_CONFIG[HOST_NAME]['site_encoding'] ?? DEFAULT_ENCODING);
define('LOGIN_ENABLED', $SITE_CONFIG[HOST_NAME]['login_enabled'] ?? false);
define('AUTH', $SITE_CONFIG[HOST_NAME]['auth'] ?? false);
// paths
// define('CSV_PATH', $PATHS[TARGET]['csv_path'] ?? '');
// define('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin'] ?? '');
// define('REDIRECT_URL', $PATHS[TARGET]['redirect_url'] ?? '');
// NOTE: everything below is smarty related and should be removed from here
/************* GENERAL PAGE TITLE ********/
define('G_TITLE', $_ENV['G_TITLE'] ?? '');
/************* LAYOUT WIDTHS *************/
define('PAGE_WIDTH', $_ENV['SMARTY.PAGE_WIDTH'] ?? '100%');
define('CONTENT_WIDTH', $_ENV['SMARTY.CONTENT_WIDTH'] ?? '100%');
// the default template name
define('MASTER_TEMPLATE_NAME', $_ENV['MASTER_TEMPLATE_NAME'] ?? 'main_body.tpl');
/************* JS LIBRARIES *************/
define('USE_PROTOTYPE', false);
define('USE_SCRIPTACULOUS', false);
define('USE_JQUERY', true);
/************ STYLE SHEETS / JS **********/
define('ADMIN_STYLESHEET', 'edit.css');
define('ADMIN_JAVASCRIPT', 'edit.js');
define('ADMIN_STYLESHEET', $_ENV['ADMIN.STYLESHEET'] ?? 'edit.css');
define('ADMIN_JAVASCRIPT', $_ENV['ADMIN.JAVASCRIPT'] ?? 'edit.js');
define('STYLESHEET', $_ENV['STYLESHEET'] ?? 'frontend.css');
define('JAVASCRIPT', $_ENV['JAVASCRIPT'] ?? 'frontend.js');
// anything optional
/************* INTERNAL ******************/
// any other global definitons in the config.other.php

View File

@@ -15,6 +15,12 @@ define('EDIT_BASE_STYLESHEET', 'edit.css');
// define('SOME_ID', <SOME VALUE>);
/************* QUEUE TABLE *************/
// if we have a dev/live system
// set_live is a per page/per item
// live_queue is a global queue system
// define('QUEUE', 'live_queue');
/************* CONVERT *******************/
// this only needed if the external thumbnail create is used
$paths = [

View File

@@ -35,4 +35,9 @@ define('CONTENT_PATH', $folder . DIRECTORY_SEPARATOR);
],
];*/
// paths
// define('CSV_PATH', $PATHS[TARGET]['csv_path'] ?? '');
// define('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin'] ?? '');
// define('REDIRECT_URL', $PATHS[TARGET]['redirect_url'] ?? '');
// __END__

View File

@@ -53,6 +53,11 @@ for (
\gullevek\dotEnv\DotEnv::readEnvFile(
$__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH
);
// load target file if it exists
\gullevek\dotEnv\DotEnv::readEnvFile(
$__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH,
'.target'
);
// load master config file that loads all other config files
require $__DIR__PATH . $CONFIG_PATH_PREFIX . CONFIG_PATH . 'config.master.php';
break;

View File

@@ -423,14 +423,9 @@ class Login
// LOGOUT TARGET
if (!isset($options['logout_target'])) {
if (defined('LOGOUT_TARGET')) {
trigger_error(
'loginMainCall: LOGOUT_TARGET should not be used',
E_USER_DEPRECATED
);
$options['logout_target'] = LOGOUT_TARGET;
$this->logout_target = $options['logout_target'];
}
// defaults to ''
$options['logout_target'] = '';
$this->logout_target = $options['logout_target'];
}
// *** PASSWORD SETTINGS
@@ -1478,6 +1473,8 @@ class Login
// username (login), group name
$this->acl['user_name'] = $_SESSION['LOGIN_USER_NAME'];
$this->acl['group_name'] = $_SESSION['LOGIN_GROUP_NAME'];
// DEPRECATED
$this->acl['euid'] = $_SESSION['LOGIN_EUID'];
// edit user cuid
$this->acl['eucuid'] = $_SESSION['LOGIN_EUCUID'];
$this->acl['eucuuid'] = $_SESSION['LOGIN_EUCUUID'];
@@ -1530,7 +1527,7 @@ class Login
$this->acl['page'] = $_SESSION['LOGIN_PAGES_ACL_LEVEL'][$this->page_name];
}
$this->acl['unit_id'] = null;
$this->acl['unit_cuid'] = null;
$this->acl['unit_name'] = null;
$this->acl['unit_uid'] = null;
$this->acl['unit'] = [];
@@ -1558,6 +1555,7 @@ class Login
'uid' => $unit['uid'],
'cuuid' => $unit['cuuid'],
'level' => $this->default_acl_list[$this->acl['unit'][$ea_cuid]]['name'] ?? -1,
'level_number' => $this->acl['unit'][$ea_cuid],
'default' => $unit['default'],
'data' => $unit['data'],
'additional_acl' => $unit['additional_acl']
@@ -2536,7 +2534,7 @@ HTML;
$this->login_user_id,
-1,
$login_user_id_changed
);
) ?? '';
// flag unclean input data
if ($login_user_id_changed > 0) {
$this->login_user_id_unclear = true;
@@ -3215,7 +3213,7 @@ HTML;
* @return int|null same edit access id if ok
* or the default edit access id
* if given one is not valid
* @deprecated Please switch to using edit access cuid check with ->loginCheckEditAccessValidCuid()
* @#deprecated Please switch to using edit access cuid check with ->loginCheckEditAccessValidCuid()
*/
public function loginCheckEditAccessId(?int $edit_access_id): ?int
{
@@ -3288,10 +3286,24 @@ HTML;
*/
public function loginGetEditAccessCuidFromId(int $id): string|false
{
if (!isset($_SESSION['LOGIN_UNIT_ACL_LEVEL'][$id])) {
if (!isset($_SESSION['LOGIN_UNIT_LEGACY'][$id])) {
return false;
}
return (string)$_SESSION['LOGIN_UNIT_ACL_LEVEL'][$id]['cuid'];
return (string)$_SESSION['LOGIN_UNIT_LEGACY'][$id]['cuid'];
}
/**
* This is a Legacy lookup from the edit access id to cuid for further lookups in the normal list
*
* @param string $cuid edit access cuid
* @return int|false false on not found or edit access id PK
*/
public function loginGetEditAccessIdFromCuid(string $cuid): int|false
{
if (!isset($_SESSION['LOGIN_UNIT'][$cuid])) {
return false;
}
return $_SESSION['LOGIN_UNIT'][$cuid]['id'];
}
/**

View File

@@ -76,7 +76,7 @@ class EditBase
);
if ($this->form->mobile_phone) {
echo "I am sorry, but this page cannot be viewed by a mobile phone";
exit;
exit(1);
}
// $this->log->debug('POST', $this->log->prAr($_POST));
}

View File

@@ -103,11 +103,7 @@ class Basic
'VIDEOS', 'DOCUMENTS', 'PDFS', 'BINARIES', 'ICONS', 'UPLOADS', 'CSV', 'JS',
'CSS', 'TABLE_ARRAYS', 'SMARTY', 'LANG', 'CACHE', 'TMP', 'LOG', 'TEMPLATES',
'TEMPLATES_C', 'DEFAULT_LANG', 'DEFAULT_ENCODING', 'DEFAULT_HASH',
'DEFAULT_ACL_LEVEL', 'LOGOUT_TARGET', 'PASSWORD_CHANGE', 'AJAX_REQUEST_TYPE',
'USE_PROTOTYPE', 'USE_SCRIPTACULOUS', 'USE_JQUERY', 'PAGE_WIDTH',
'MASTER_TEMPLATE_NAME', 'PUBLIC_SCHEMA', 'TEST_SCHEMA', 'DEV_SCHEMA',
'LIVE_SCHEMA', 'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET', 'DEBUG',
'SHOW_ALL_ERRORS'
'DB_CONFIG_NAME', 'DB_CONFIG', 'TARGET'
] as $constant
) {
if (!defined($constant)) {

View File

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

View File

@@ -10,9 +10,16 @@ namespace CoreLibs\Convert;
class Html
{
/** @var int */
public const SELECTED = 0;
/** @var int */
public const CHECKED = 1;
// TODO: check for not valid htmlentites encoding
// as of PHP 8.4: https://www.php.net/manual/en/function.htmlentities.php
/** @#var array<string> */
// public const VALID_HTMLENT_ENCODINGS = [];
/**
* full wrapper for html entities
*
@@ -22,14 +29,19 @@ class Html
* encodes in UTF-8
* does not double encode
*
* @param mixed $string string to html encode
* @param int $flags [default: ENT_QUOTES | ENT_HTML5]
* @param mixed $string string to html encode
* @param int $flags [default=ENT_QUOTES | ENT_HTML5]
* @param string $encoding [default=UTF-8]
* @return mixed if string, encoded, else as is (eg null)
*/
public static function htmlent(mixed $string, int $flags = ENT_QUOTES | ENT_HTML5): mixed
{
public static function htmlent(
mixed $string,
int $flags = ENT_QUOTES | ENT_HTML5,
string $encoding = 'UTF-8'
): mixed {
if (is_string($string)) {
return htmlentities($string, $flags, 'UTF-8', false);
// if not a valid encoding this will throw a warning and use UTF-8
return htmlentities($string, $flags, $encoding, false);
}
return $string;
}
@@ -37,7 +49,7 @@ class Html
/**
* strips out all line breaks or replaced with given string
* @param string $string string
* @param string $replace replace character, default ' '
* @param string $replace [default=' '] replace character
* @return string cleaned string without any line breaks
*/
public static function removeLB(string $string, string $replace = ' '): string

View File

@@ -500,7 +500,7 @@ class IO
die('<!-- Cannot load db functions class for: ' . $this->db_type . ' -->');
}
// write to internal one, once OK
$this->db_functions = $db_functions;
$this->db_functions = $db_functions; /** @phan-suppress-current-line PhanPossiblyNullTypeMismatchProperty */
// connect to DB
if (!$this->__connectToDB()) {
@@ -1413,10 +1413,7 @@ class IO
$this->pk_name_table[$table] ?
$this->pk_name_table[$table] : 'NULL';
}
if (
!preg_match(self::REGEX_RETURNING, $this->query) &&
$this->pk_name && $this->pk_name != 'NULL'
) {
if (!preg_match(self::REGEX_RETURNING, $this->query) && $this->pk_name != 'NULL') {
// check if this query has a ; at the end and remove it
$__query = preg_replace("/(;\s*)$/", '', $this->query);
// must be query, if preg replace failed, use query as before
@@ -1426,7 +1423,7 @@ class IO
} elseif (
preg_match(self::REGEX_RETURNING, $this->query, $matches)
) {
if ($this->pk_name && $this->pk_name != 'NULL') {
if ($this->pk_name != 'NULL') {
// add the primary key if it is not in the returning set
if (!preg_match("/$this->pk_name/", $matches[1])) {
$this->query .= " , " . $this->pk_name;
@@ -2946,7 +2943,7 @@ class IO
$query_hash = $this->dbGetQueryHash($query, $params);
// clears cache for this query
if (empty($this->cursor_ext[$query_hash]['query'])) {
$this->__dbError(18, context: [
$this->__dbWarning(18, context: [
'query' => $query,
'params' => $params,
'hash' => $query_hash,
@@ -3141,6 +3138,7 @@ class IO
'pk_name' => '',
'count' => 0,
'query' => '',
'query_raw' => $query,
'result' => null,
'returning_id' => false,
'placeholder_converted' => [],
@@ -3237,11 +3235,12 @@ class IO
}
} else {
// if we try to use the same statement name for a differnt query, error abort
if ($this->prepare_cursor[$stm_name]['query'] != $query) {
if ($this->prepare_cursor[$stm_name]['query_raw'] != $query) {
// thrown error
$this->__dbError(26, false, context: [
'statement_name' => $stm_name,
'prepared_query' => $this->prepare_cursor[$stm_name]['query'],
'prepared_query_raw' => $this->prepare_cursor[$stm_name]['query_raw'],
'query' => $query,
'pk_name' => $pk_name,
]);
@@ -4364,6 +4363,37 @@ class IO
return $this->prepare_cursor[$stm_name][$key];
}
/**
* Checks if a prepared query eixsts
*
* @param string $stm_name Statement to check
* @param string $query [default=''] If set then query must also match
* @return false|int<0,2> False on missing stm_name
* 0: ok, 1: stm_name matchin, 2: stm_name and query matching
*/
public function dbPreparedCursorStatus(string $stm_name, string $query = ''): false|int
{
if (empty($stm_name)) {
$this->__dbError(
101,
false,
'No statement name given'
);
return false;
}
// does not exist
$return_value = 0;
if (!empty($this->prepare_cursor[$stm_name]['query_raw'])) {
// statement name eixts
$return_value = 1;
if ($this->prepare_cursor[$stm_name]['query_raw'] == $query) {
// query also matches
$return_value = 2;
}
}
return $return_value;
}
// ***************************
// ERROR AND WARNING DATA
// ***************************

View File

@@ -0,0 +1,95 @@
<?php
/**
* AUTHOR: Clemens Schwaighofer
* CREATED: 2025/1/17
* DESCRIPTION:
* Deprecated helper for fputcsv
*/
declare(strict_types=1);
namespace CoreLibs\DeprecatedHelper;
use InvalidArgumentException;
class Deprecated84
{
/**
* This is a wrapper for fputcsv to fix deprecated warning for $escape parameter
* See: https://www.php.net/manual/en/function.fputcsv.php
* escape parameter deprecation and recommend to set to "" for compatible with PHP 9.0
*
* @param mixed $stream
* @param array<mixed> $fields
* @param string $separator
* @param string $enclosure
* @param string $escape
* @param string $eol
* @return int|false
* @throws InvalidArgumentException
*/
public static function fputcsv(
mixed $stream,
array $fields,
string $separator = ",",
string $enclosure = '"',
string $escape = '', // set to empty for future compatible
string $eol = PHP_EOL
): int | false {
if (!is_resource($stream)) {
throw new \InvalidArgumentException("fputcsv stream parameter must be a resrouce");
}
return fputcsv($stream, $fields, $separator, $enclosure, $escape, $eol);
}
/**
* This is a wrapper for fgetcsv to fix deprecated warning for $escape parameter
* See: https://www.php.net/manual/en/function.fgetcsv.php
* escape parameter deprecation and recommend to set to "" for compatible with PHP 9.0
*
* @param mixed $stream
* @param null|int<0,max> $length
* @param string $separator
* @param string $enclosure
* @param string $escape
* @return array<mixed>|false
* @throws InvalidArgumentException
*/
public static function fgetcsv(
mixed $stream,
?int $length = null,
string $separator = ',',
string $enclosure = '"',
string $escape = '' // set to empty for future compatible
): array | false {
if (!is_resource($stream)) {
throw new \InvalidArgumentException("fgetcsv stream parameter must be a resrouce");
}
return fgetcsv($stream, $length, $separator, $enclosure, $escape);
}
/**
* This is a wrapper for str_getcsv to fix deprecated warning for $escape parameter
* See: https://www.php.net/manual/en/function.str-getcsv.php
* escape parameter deprecation and recommend to set to "" for compatible with PHP 9.0
*
* @param string $string
* @param string $separator
* @param string $enclosure
* @param string $escape
* @return array<mixed>
*/
// phpcs:disable PSR1.Methods.CamelCapsMethodName
public static function str_getcsv(
string $string,
string $separator = ",",
string $enclosure = '"',
string $escape = '' // set to empty for future compatible
): array {
return str_getcsv($string, $separator, $enclosure, $escape);
}
// phpcs:enable PSR1.Methods.CamelCapsMethodName
}
// __END__

View File

@@ -50,7 +50,6 @@ class GetLocale
$locale = defined('SITE_LOCALE') && !empty(SITE_LOCALE) ?
SITE_LOCALE :
// else parse from default, if not 'en'
/** @phpstan-ignore-next-line DEFAULT_LOCALE could be empty */
(defined('DEFAULT_LOCALE') && !empty(DEFAULT_LOCALE) ?
DEFAULT_LOCALE : 'en');
}
@@ -97,8 +96,7 @@ class GetLocale
$encoding = defined('SITE_ENCODING') && !empty(SITE_ENCODING) ?
SITE_ENCODING :
// or default encoding, if not 'UTF-8'
/** @phpstan-ignore-next-line DEFAULT_LOCALE could be empty */
(defined('DEFAULT_ENCODING') && !empty(DEFAULT_ENCODING) ?
(defined('DEFAULT_ENCODING') ?
DEFAULT_ENCODING : 'UTF-8');
}
}

View File

@@ -30,6 +30,10 @@ class Logging
{
/** @var int minimum size for a max file size, so we don't set 1 byte, 10kb */
public const MIN_LOG_MAX_FILESIZE = 10 * 1024;
/** @var string log file extension, not changeable */
private const LOG_FILE_NAME_EXT = "log";
/** @var string log file block separator, not changeable */
private const LOG_FILE_BLOCK_SEPARATOR = '.';
// NOTE: the second party array{} hs some errors
/** @var array<string,array<string,string|bool|Level>>|array{string:array{type:string,type_info?:string,mandatory:true,alias?:string,default:string|bool|Level,deprecated:bool,use?:string}} */
@@ -104,8 +108,6 @@ class Logging
private string $log_folder = '';
/** @var string a alphanumeric name that has to be set as global definition */
private string $log_file_id = '';
/** @var string log file name extension */
private string $log_file_name_ext = 'log';
/** @var string log file name with folder, for actual writing */
private string $log_file_name = '';
/** @var int set in bytes */
@@ -431,7 +433,7 @@ class Logging
private function buildLogFileName(Level $level, string $group_id = ''): string
{
// init base file path
$fn = $this->log_print_file . '.' . $this->log_file_name_ext;
$fn = $this->log_print_file . '.' . self::LOG_FILE_NAME_EXT;
// log ID prefix settings, if not valid, replace with empty
if (!empty($this->log_file_id)) {
$rpl_string = $this->log_file_id;
@@ -440,14 +442,15 @@ class Logging
}
$fn = str_replace('{LOGID}', $rpl_string, $fn); // log id (like a log file prefix)
$rpl_string = !$this->getLogFlag(Flag::per_level) ? '' :
'_' . $level->getName();
$rpl_string = $this->getLogFlag(Flag::per_level) ?
self::LOG_FILE_BLOCK_SEPARATOR . $level->getName() :
'';
$fn = str_replace('{LEVEL}', $rpl_string, $fn); // create output filename
// write per level
$rpl_string = !$this->getLogFlag(Flag::per_group) ? '' :
$rpl_string = $this->getLogFlag(Flag::per_group) ?
// normalize level, replace all non alphanumeric characters with -
'_' . (
self::LOG_FILE_BLOCK_SEPARATOR . (
// if return is only - then set error string
preg_match(
"/^-+$/",
@@ -455,25 +458,29 @@ class Logging
) ?
'INVALID-LEVEL-STRING' :
$level_string
);
) :
'';
$fn = str_replace('{GROUP}', $rpl_string, $fn); // create output filename
// set per class, but don't use get_class as we will only get self
$rpl_string = !$this->getLogFlag(Flag::per_class) ? '' : '_'
// set sub class settings
. str_replace('\\', '-', Support::getCallerTopLevelClass());
$rpl_string = $this->getLogFlag(Flag::per_class) ?
// set sub class settings
self::LOG_FILE_BLOCK_SEPARATOR . str_replace('\\', '-', Support::getCallerTopLevelClass()) :
'';
$fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename
// if request to write to one file
$rpl_string = !$this->getLogFlag(Flag::per_page) ?
'' :
'_' . System::getPageName(System::NO_EXTENSION);
$rpl_string = $this->getLogFlag(Flag::per_page) ?
self::LOG_FILE_BLOCK_SEPARATOR . System::getPageName(System::NO_EXTENSION) :
'';
$fn = str_replace('{PAGENAME}', $rpl_string, $fn); // create output filename
// if run id, we auto add ymd, so we ignore the log file date
if ($this->getLogFlag(Flag::per_run)) {
$rpl_string = '_' . $this->getLogUniqueId(); // add 8 char unique string
// add 8 char unique string and date block with time
$rpl_string = self::LOG_FILE_BLOCK_SEPARATOR . $this->getLogUniqueId();
} elseif ($this->getLogFlag(Flag::per_date)) {
$rpl_string = '_' . $this->getLogDate(); // add date to file
// add date to file
$rpl_string = self::LOG_FILE_BLOCK_SEPARATOR . $this->getLogDate();
} else {
$rpl_string = '';
}
@@ -739,7 +746,10 @@ class Logging
{
if (empty($this->log_file_unique_id) || $override == true) {
$this->log_file_unique_id =
date('Y-m-d_His') . '_U_'
date('Y-m-d_His')
. self::LOG_FILE_BLOCK_SEPARATOR
. 'U_'
// this doesn't have to be unique for everything, just for this logging purpose
. substr(hash(
'sha1',
random_bytes(63)

View File

@@ -418,9 +418,7 @@ class ProgressBar
// if this is percent, we ignore anything, it is auto positioned
if ($this->label[$name]['type'] != 'percent') {
foreach (['top', 'left', 'width', 'height'] as $pos_name) {
if ($$pos_name !== false) {
$this->label[$name][$pos_name] = intval($$pos_name);
}
$this->label[$name][$pos_name] = intval($$pos_name);
}
if ($align != '') {