Compare commits

...

11 Commits

Author SHA1 Message Date
Clemens Schwaighofer
a7742bd5c8 DB IO count params fix for comments 2024-12-10 13:36:57 +09:00
Clemens Schwaighofer
78591d6ba4 Fix Param regex lookup
Query was not counting params after "--" comment strings
2024-12-10 12:01:06 +09:00
Clemens Schwaighofer
98bf3a40cd Add logout button to class.test.php for logout test, ANY placeholder db test 2024-12-06 14:54:09 +09:00
Clemens Schwaighofer
cbd47fb015 edit log table update, Change all DB tests serial to identity for primary key 2024-12-05 14:59:49 +09:00
Clemens Schwaighofer
5f89917abd Add composer keywords 2024-12-05 14:30:12 +09:00
Clemens Schwaighofer
eeaff3042e phpstan config file update with phpVersion information 2024-12-05 14:16:57 +09:00
Clemens Schwaighofer
d070c4e461 phan min php set to 8.2 2024-12-05 13:59:20 +09:00
Clemens Schwaighofer
e57c336dba Clean up to use session methods and not _SESSION directly
Add session_unset for unsetAll and rename this method to "clear"
2024-12-05 13:52:45 +09:00
Clemens Schwaighofer
075fe967d5 Merge branch 'NewFeatures' into Feature-FixSessionClass 2024-12-05 12:18:51 +09:00
Clemens Schwaighofer
0e5f637052 Update Serial to Identity function
Return status as varchar from change.

clean up edit table SQL files with too many empty lines
2024-12-05 12:11:07 +09:00
Clemens Schwaighofer
2e1b767a85 Fix Session class with Many update and get
Update Login and Backend class to use interface when writing to avoid
problems with not written _SESSION vars with session is in write close status
2024-12-05 12:09:58 +09:00
20 changed files with 471 additions and 251 deletions

View File

@@ -27,7 +27,7 @@ use Phan\Config;
return [ return [
// "target_php_version" => "8.2", // "target_php_version" => "8.2",
"minimum_target_php_version" => "8.1", "minimum_target_php_version" => "8.2",
// turn color on (-C) // turn color on (-C)
"color_issue_messages_if_supported" => true, "color_issue_messages_if_supported" => true,
// If true, missing properties will be created when // If true, missing properties will be created when

View File

@@ -6,7 +6,8 @@
-- @param name col The column to be changed -- @param name col The column to be changed
-- @param varchar identity_type [default=a] Allowed a, d, assigned, default -- @param varchar identity_type [default=a] Allowed a, d, assigned, default
-- @param varchar col_type [default=''] Allowed smallint, int, bigint, int2, int4, int8 -- @param varchar col_type [default=''] Allowed smallint, int, bigint, int2, int4, int8
-- @raises EXCEPTON on column not found, no linked sequence, more than one linked sequence found -- @returns varchar status tring
-- @raises EXCEPTON on column not found, no linked sequence, more than one linked sequence found, invalid col type
-- --
CREATE OR REPLACE FUNCTION upgrade_serial_to_identity( CREATE OR REPLACE FUNCTION upgrade_serial_to_identity(
tbl regclass, tbl regclass,
@@ -14,17 +15,18 @@ CREATE OR REPLACE FUNCTION upgrade_serial_to_identity(
identity_type varchar = 'a', identity_type varchar = 'a',
col_type varchar = '' col_type varchar = ''
) )
RETURNS void RETURNS varchar
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
colnum smallint; colnum SMALLINT;
seqid oid; seqid OID;
count int; count INT;
col_type_oid int; col_type_oid INT;
col_type_len int; col_type_len INT;
current_col_atttypid oid; current_col_atttypid OID;
current_col_attlen int; current_col_attlen INT;
status_string VARCHAR;
BEGIN BEGIN
-- switch between always (default) or default identiy type -- switch between always (default) or default identiy type
IF identity_type NOT IN ('a', 'd', 'assigned', 'default') THEN IF identity_type NOT IN ('a', 'd', 'assigned', 'default') THEN
@@ -59,6 +61,10 @@ BEGIN
RAISE EXCEPTION 'more than one linked sequence found'; RAISE EXCEPTION 'more than one linked sequence found';
END IF; END IF;
IF col_type <> '' AND col_type NOT IN ('smallint', 'int', 'bigint', 'int2', 'int4', 'int8') THEN
RAISE EXCEPTION 'Invalid col type: %', col_type;
END IF;
-- drop the default -- drop the default
EXECUTE 'ALTER TABLE ' || tbl || ' ALTER COLUMN ' || quote_ident(col) || ' DROP DEFAULT'; EXECUTE 'ALTER TABLE ' || tbl || ' ALTER COLUMN ' || quote_ident(col) || ' DROP DEFAULT';
@@ -74,34 +80,31 @@ BEGIN
SET attidentity = identity_type SET attidentity = identity_type
WHERE attrelid = tbl WHERE attrelid = tbl
AND attname = col; AND attname = col;
RAISE NOTICE 'Update to identity for table "%" and columen "%" with type "%"', tbl, col, identity_type; status_string := 'Updated to identity for table "' || tbl || '" and columen "' || col || '" with type "' || identity_type || '"';
-- set type if requested and not empty -- set type if requested and not empty
IF col_type <> '' THEN IF col_type <> '' THEN
IF col_type IN ('smallint', 'int', 'bigint', 'int2', 'int4', 'int8') THEN -- rewrite smallint, int, bigint
-- rewrite smallint, int, bigint IF col_type = 'smallint' THEN
IF col_type = 'smallint' THEN col_type := 'int2';
col_type := 'int2'; ELSIF col_type = 'int' THEN
ELSIF col_type = 'int' THEN col_type := 'int4';
col_type := 'int4'; ELSIF col_type = 'bigint' THEN
ELSIF col_type = 'bigint' THEN col_type := 'int8';
col_type := 'int8'; END IF;
END IF; -- get the length and oid for selected
-- get the length and oid for selected SELECT oid, typlen INTO col_type_oid, col_type_len FROM pg_type WHERE typname = col_type;
SELECT oid, typlen INTO col_type_oid, col_type_len FROM pg_type WHERE typname = col_type; -- set only if diff or hight
-- set only if diff or hight IF current_col_atttypid <> col_type_oid AND col_type_len > current_col_attlen THEN
IF current_col_atttypid <> col_type_oid AND col_type_len > current_col_attlen THEN status_string := status_string || '. Change col type: ' || col_type;
RAISE NOTICE 'Change col type: %', col_type; -- update type
-- update type UPDATE pg_attribute
UPDATE pg_attribute SET
SET atttypid = col_type_oid, attlen = col_type_len
atttypid = col_type_oid, attlen = col_type_len WHERE attrelid = tbl
WHERE attrelid = tbl AND attname = col;
AND attname = col;
END IF;
ELSE
RAISE NOTICE 'Invalid col type: %', col_type;
END IF; END IF;
END IF; END IF;
RETURN status_string;
END; END;
$$; $$;

View File

@@ -10,10 +10,10 @@ CREATE TABLE edit_log (
edit_log_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, edit_log_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
euid INT, -- this is a foreign key, but I don't nedd to reference to it euid INT, -- this is a foreign key, but I don't nedd to reference to it
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL, FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
username VARCHAR,
password VARCHAR,
ecuid VARCHAR, ecuid VARCHAR,
ecuuid UUID, ecuuid UUID,
username VARCHAR,
password VARCHAR,
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP, event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
ip VARCHAR, ip VARCHAR,
error TEXT, error TEXT,

View File

@@ -12,5 +12,3 @@ CREATE TABLE edit_menu_group (
flag VARCHAR, flag VARCHAR,
order_number INT NOT NULL order_number INT NOT NULL
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -16,5 +16,3 @@ CREATE TABLE edit_page_access (
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0 enabled SMALLINT NOT NULL DEFAULT 0
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;

View File

@@ -321,7 +321,7 @@ CREATE TABLE edit_generic (
-- DROP TABLE edit_visible_group; -- DROP TABLE edit_visible_group;
CREATE TABLE edit_visible_group ( CREATE TABLE edit_visible_group (
edit_visible_group_id SERIAL PRIMARY KEY, edit_visible_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR, name VARCHAR,
flag VARCHAR flag VARCHAR
) INHERITS (edit_generic) WITHOUT OIDS; ) INHERITS (edit_generic) WITHOUT OIDS;
@@ -336,7 +336,7 @@ CREATE TABLE edit_visible_group (
-- DROP TABLE edit_menu_group; -- DROP TABLE edit_menu_group;
CREATE TABLE edit_menu_group ( CREATE TABLE edit_menu_group (
edit_menu_group_id SERIAL PRIMARY KEY, edit_menu_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR, name VARCHAR,
flag VARCHAR, flag VARCHAR,
order_number INT NOT NULL order_number INT NOT NULL
@@ -354,7 +354,7 @@ CREATE TABLE edit_menu_group (
-- DROP TABLE edit_page; -- DROP TABLE edit_page;
CREATE TABLE edit_page ( CREATE TABLE edit_page (
edit_page_id SERIAL PRIMARY KEY, edit_page_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE, FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
filename VARCHAR, filename VARCHAR,
@@ -378,7 +378,7 @@ CREATE TABLE edit_page (
-- DROP TABLE edit_query_string; -- DROP TABLE edit_query_string;
CREATE TABLE edit_query_string ( CREATE TABLE edit_query_string (
edit_query_string_id SERIAL PRIMARY KEY, edit_query_string_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
edit_page_id INT NOT NULL, edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
@@ -430,7 +430,7 @@ CREATE TABLE edit_page_menu_group (
-- DROP TABLE edit_access_right; -- DROP TABLE edit_access_right;
CREATE TABLE edit_access_right ( CREATE TABLE edit_access_right (
edit_access_right_id SERIAL PRIMARY KEY, edit_access_right_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name VARCHAR, name VARCHAR,
level SMALLINT, level SMALLINT,
type VARCHAR, type VARCHAR,
@@ -447,7 +447,7 @@ CREATE TABLE edit_access_right (
-- DROP TABLE edit_scheme; -- DROP TABLE edit_scheme;
CREATE TABLE edit_scheme ( CREATE TABLE edit_scheme (
edit_scheme_id SERIAL PRIMARY KEY, edit_scheme_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
name VARCHAR, name VARCHAR,
header_color VARCHAR, header_color VARCHAR,
@@ -466,7 +466,7 @@ CREATE TABLE edit_scheme (
-- DROP TABLE edit_language; -- DROP TABLE edit_language;
CREATE TABLE edit_language ( CREATE TABLE edit_language (
edit_language_id SERIAL PRIMARY KEY, edit_language_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
lang_default SMALLINT NOT NULL DEFAULT 0, lang_default SMALLINT NOT NULL DEFAULT 0,
long_name VARCHAR, long_name VARCHAR,
@@ -485,7 +485,7 @@ CREATE TABLE edit_language (
-- DROP TABLE edit_group; -- DROP TABLE edit_group;
CREATE TABLE edit_group ( CREATE TABLE edit_group (
edit_group_id SERIAL PRIMARY KEY, edit_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
edit_scheme_id INT, edit_scheme_id INT,
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL, edit_access_right_id INT NOT NULL,
@@ -507,7 +507,7 @@ CREATE TABLE edit_group (
-- DROP TABLE edit_page_access; -- DROP TABLE edit_page_access;
CREATE TABLE edit_page_access ( CREATE TABLE edit_page_access (
edit_page_access_id SERIAL PRIMARY KEY, edit_page_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
edit_group_id INT NOT NULL, edit_group_id INT NOT NULL,
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_page_id INT NOT NULL, edit_page_id INT NOT NULL,
@@ -530,7 +530,7 @@ CREATE TABLE edit_page_access (
-- DROP TABLE edit_page_content; -- DROP TABLE edit_page_content;
CREATE TABLE edit_page_content ( CREATE TABLE edit_page_content (
edit_page_content_id SERIAL PRIMARY KEY, edit_page_content_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
edit_page_id INT NOT NULL, edit_page_id INT NOT NULL,
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_access_right_id INT NOT NULL, edit_access_right_id INT NOT NULL,
@@ -551,7 +551,7 @@ CREATE TABLE edit_page_content (
-- DROP TABLE edit_user; -- DROP TABLE edit_user;
CREATE TABLE edit_user ( CREATE TABLE edit_user (
edit_user_id SERIAL PRIMARY KEY, edit_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
connect_edit_user_id INT, -- possible reference to other user connect_edit_user_id INT, -- possible reference to other user
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_language_id INT NOT NULL, edit_language_id INT NOT NULL,
@@ -652,11 +652,11 @@ COMMENT ON COLUMN edit_user.additional_acl IS 'Additional Access Control List st
-- DROP TABLE edit_log; -- DROP TABLE edit_log;
CREATE TABLE edit_log ( CREATE TABLE edit_log (
edit_log_id SERIAL PRIMARY KEY, edit_log_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
euid INT, -- this is a foreign key, but I don't nedd to reference to it euid INT, -- this is a foreign key, but I don't nedd to reference to it
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
ecuid VARCHAR, ecuid VARCHAR,
ecuuid UUID, ecuuid UUID,
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
username VARCHAR, username VARCHAR,
password VARCHAR, password VARCHAR,
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP, event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
@@ -712,7 +712,7 @@ ALTER TABLE edit_log_overflow ADD CONSTRAINT edit_log_overflow_euid_fkey FOREIGN
-- DROP TABLE edit_access; -- DROP TABLE edit_access;
CREATE TABLE edit_access ( CREATE TABLE edit_access (
edit_access_id SERIAL PRIMARY KEY, edit_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,
protected SMALLINT DEFAULT 0, protected SMALLINT DEFAULT 0,
deleted SMALLINT DEFAULT 0, deleted SMALLINT DEFAULT 0,
@@ -733,7 +733,7 @@ CREATE TABLE edit_access (
-- DROP TABLE edit_access_user; -- DROP TABLE edit_access_user;
CREATE TABLE edit_access_user ( CREATE TABLE edit_access_user (
edit_access_user_id SERIAL PRIMARY KEY, edit_access_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
edit_access_id INT NOT NULL, edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
edit_user_id INT NOT NULL, edit_user_id INT NOT NULL,
@@ -754,7 +754,7 @@ CREATE TABLE edit_access_user (
-- DROP TABLE edit_access_data; -- DROP TABLE edit_access_data;
CREATE TABLE edit_access_data ( CREATE TABLE edit_access_data (
edit_access_data_id SERIAL PRIMARY KEY, edit_access_data_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
edit_access_id INT NOT NULL, edit_access_id INT NOT NULL,
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
enabled SMALLINT NOT NULL DEFAULT 0, enabled SMALLINT NOT NULL DEFAULT 0,

View File

@@ -272,24 +272,27 @@ final class CoreLibsCreateSessionTest extends TestCase
* *
* @return array * @return array
*/ */
public function sessionDataProvider(): array public function providerSessionData(): array
{ {
return [ return [
'test' => [ 'test' => [
'foo', 'foo',
'bar', 'bar',
'bar', 'bar',
null,
], ],
'int key test' => [ 'int key test' => [
123, 123,
'bar', 'bar',
'bar', 'bar',
\UnexpectedValueException::class
], ],
// more complex value tests // more complex value tests
'array values' => [ 'array values' => [
'array', 'array',
[1, 2, 3], [1, 2, 3],
[1, 2, 3], [1, 2, 3],
null,
] ]
]; ];
} }
@@ -299,21 +302,28 @@ final class CoreLibsCreateSessionTest extends TestCase
/** /**
* method call test * method call test
* *
* @covers ::setS * @covers ::set
* @covers ::getS * @covers ::get
* @covers ::issetS * @covers ::isset
* @covers ::unsetS * @covers ::unset
* @dataProvider sessionDataProvider * @dataProvider providerSessionData
* @testdox setS/getS/issetS/unsetS $name with $input is $expected [$_dataName] * @testdox set/get/isset/unset $name with $input is $expected ($exception) [$_dataName]
* *
* @param string|int $name * @param string|int $name
* @param mixed $input * @param mixed $input
* @param mixed $expected * @param mixed $expected
* @param ?mixed $exception
* @return void * @return void
*/ */
/* public function testMethodSetGet($name, $input, $expected): void public function testMethodSetGet($name, $input, $expected, $exception): void
{ {
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testMethodSetGet in CLI');
}
$session = new \CoreLibs\Create\Session('TEST_METHOD'); $session = new \CoreLibs\Create\Session('TEST_METHOD');
if ($expected !== null) {
$this->expectException($exception);
}
$session->set($name, $input); $session->set($name, $input);
$this->assertEquals( $this->assertEquals(
$expected, $expected,
@@ -331,12 +341,80 @@ final class CoreLibsCreateSessionTest extends TestCase
$session->get($name), $session->get($name),
'method unset assert' 'method unset assert'
); );
// iset false // isset false
$this->assertFalse( $this->assertFalse(
$session->isset($name), $session->isset($name),
'method isset assert false' 'method isset assert false'
); );
} */ }
/**
* Undocumented function
*
* @return array
*/
public function providerSessionDataMany(): array
{
return [
'valid set' => [
[
'foo 1' => 'bar 1',
'foo 2' => 'bar 1',
],
[
'foo 1' => 'bar 1',
'foo 2' => 'bar 1',
],
null,
],
'invalid entry' => [
[
'foo 1' => 'bar 1',
123 => 'bar 1',
],
[
'foo 1' => 'bar 1',
],
\UnexpectedValueException::class
]
];
}
/**
* Undocumented function
*
* @covers ::setMany
* @covers ::getMany
* @dataProvider providerSessionDataMany
* @testdox setMany/getMany/unsetMany $set is $expected ($exception) [$_dataName]
*
* @param array<string|int,mixed> $set
* @param array<string,mixed> $expected
* @param ?mixed $exception
* @return void
*/
public function testMany($set, $expected, $exception): void
{
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testMethodSetGet in CLI');
}
$session = new \CoreLibs\Create\Session('TEST_METHOD');
if ($expected !== null) {
$this->expectException($exception);
}
$session->setMany($set);
$this->assertEquals(
$expected,
$session->getMany(array_keys($set)),
'set many failed'
);
$session->unsetMany(array_keys($set));
$this->assertEquals(
[],
$session->getMany(array_keys($set)),
'unset many failed'
);
}
/** /**
* unset all test * unset all test
@@ -346,8 +424,11 @@ final class CoreLibsCreateSessionTest extends TestCase
* *
* @return void * @return void
*/ */
/* public function testUnsetAll(): void public function testUnsetAll(): void
{ {
if (\CoreLibs\Get\System::checkCLI()) {
$this->markTestSkipped('Cannot run testUnsetAll in CLI');
}
$test_values = [ $test_values = [
'foo' => 'abc', 'foo' => 'abc',
'bar' => '123' 'bar' => '123'
@@ -363,7 +444,7 @@ final class CoreLibsCreateSessionTest extends TestCase
); );
} }
// unset all // unset all
$session->unsetAll(); $session->clear();
// check unset // check unset
foreach (array_keys($test_values) as $name) { foreach (array_keys($test_values) as $name) {
$this->assertEquals( $this->assertEquals(
@@ -372,7 +453,7 @@ final class CoreLibsCreateSessionTest extends TestCase
'unsert assert: ' . $name 'unsert assert: ' . $name
); );
} }
} */ }
} }
// __END__ // __END__

View File

@@ -17,7 +17,7 @@ Table with Primary Key: table_with_primary_key
Table without Primary Key: table_without_primary_key Table without Primary Key: table_without_primary_key
Table with primary key has additional row: Table with primary key has additional row:
row_primary_key SERIAL PRIMARY KEY, row_primary_key INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
Each table has the following rows Each table has the following rows
row_int INT, row_int INT,
row_numeric NUMERIC, row_numeric NUMERIC,
@@ -160,7 +160,6 @@ final class CoreLibsDBIOTest extends TestCase
// create the tables // create the tables
$db->dbExec( $db->dbExec(
// primary key name is table + '_id' // primary key name is table + '_id'
// table_with_primary_key_id SERIAL PRIMARY KEY,
<<<SQL <<<SQL
CREATE TABLE table_with_primary_key ( CREATE TABLE table_with_primary_key (
table_with_primary_key_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, table_with_primary_key_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
@@ -5136,6 +5135,39 @@ final class CoreLibsDBIOTest extends TestCase
SQL, SQL,
'count' => 6, 'count' => 6,
'convert' => false, 'convert' => false,
],
'comments in insert' => [
'query' => <<<SQL
INSERT INTO table_with_primary_key (
row_int, row_numeric, row_varchar, row_varchar_literal
) VALUES (
-- comment 1
$1, $2,
-- comment 2
$3
-- comment 3
, $4
)
SQL,
'count' => 4,
'convert' => false
],
// Note some are not set
'a complete set of possible' => [
'query' => <<<SQL
UPDATE table_with_primary_key SET
-- ROW
row_varchar = $1
WHERE
row_varchar = ANY($2) AND row_varchar <> $3
AND row_varchar > $4 AND row_varchar < $5
AND row_varchar >= $6 AND row_varchar <=$7
AND row_jsonb->'a' = $8 AND row_jsonb->>$9 = 'a'
AND row_jsonb<@$10 AND row_jsonb@>$11
AND row_varchar ^@ $12
SQL,
'count' => 12,
'convert' => false,
] ]
]; ];
} }

View File

@@ -2,6 +2,7 @@
"name": "egrajp/development-corelibs-dev", "name": "egrajp/development-corelibs-dev",
"version": "dev-master", "version": "dev-master",
"description": "CoreLibs: Development package", "description": "CoreLibs: Development package",
"keywords": ["corelib", "logging", "database", "templating", "tools"],
"type": "library", "type": "library",
"require": { "require": {
"php": ">=8.3" "php": ">=8.3"

View File

@@ -14,6 +14,9 @@ parameters:
# allRules: false # allRules: false
checkMissingCallableSignature: true checkMissingCallableSignature: true
treatPhpDocTypesAsCertain: false treatPhpDocTypesAsCertain: false
# phpVersion:
# min: 80200 # PHP 8.2.0
# max: 80300 # PHP latest
paths: paths:
- %currentWorkingDirectory%/www - %currentWorkingDirectory%/www
bootstrapFiles: bootstrapFiles:

View File

@@ -115,6 +115,21 @@ echo "INSERT ALL COLUMN TYPES: "
. "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>";
// test connectors: = , <> () for query detection // test connectors: = , <> () for query detection
// convert placeholder tests // convert placeholder tests

View File

@@ -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';
@@ -70,10 +72,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 +90,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,

View File

@@ -62,9 +62,30 @@ $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 = [
@@ -205,8 +226,8 @@ 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 "ECUID: " . $_SESSION['ECUID'] . "<br>"; print "ECUID: " . $session->get('ECUID') . "<br>";
print "ECUUID: " . $_SESSION['ECUUID'] . "<br>"; print "ECUUID: " . $session->get('ECUUID') . "<br>";
print "</body></html>"; print "</body></html>";

View File

@@ -45,6 +45,7 @@ $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;
$PAGE_NAME = 'TEST CLASS: SESSION'; $PAGE_NAME = 'TEST CLASS: SESSION';
@@ -56,7 +57,7 @@ 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 . "': " print "Valid session name static check for '" . $session_name . "': "
. \CoreLibs\Debug\Support::prBl(Session::checkValidSessionName($session_name)) . "<br>"; . Support::prBl(Session::checkValidSessionName($session_name)) . "<br>";
$var = 'foo'; $var = 'foo';
$value = 'bar'; $value = 'bar';
$session = new Session($session_name); $session = new Session($session_name);
@@ -96,13 +97,27 @@ print "[READ WRAP] Isset: " . ($session->isset('setwrap') ? 'Yes' : 'No') . "<br
$session->unset('setwrap'); $session->unset('setwrap');
print "[READ WRAP] unset setwrap: " . $session->get('setwrap') . "<br>"; print "[READ WRAP] unset setwrap: " . $session->get('setwrap') . "<br>";
print "[READ WRAP] unset Isset: " . ($session->isset('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>"; print "<hr>";
// differnt session name // differnt session name
@@ -115,7 +130,8 @@ try {
print "[3 FAILED] Session start failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><br>"; print "[3 FAILED] Session start failed:<br>" . $e->getMessage() . "<br><pre>" . $e . "</pre><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();
@@ -142,7 +158,7 @@ try {
} }
$_SESSION['will_be_written_again'] = 'Full'; $_SESSION['will_be_written_again'] = 'Full';
print "[ALL SESSION]: " . \CoreLibs\Debug\Support::printAr($_SESSION) . "<br>"; print "[ALL SESSION]: " . Support::printAr($_SESSION) . "<br>";
// close session // close session
$session->writeClose(); $session->writeClose();

View File

@@ -372,9 +372,6 @@ class Login
], ],
]; ];
// init default ACL list array
$_SESSION['DEFAULT_ACL_LIST'] = [];
$_SESSION['DEFAULT_ACL_LIST_TYPE'] = [];
// read the current edit_access_right list into an array // read the current edit_access_right list into an array
$q = "SELECT level, type, name FROM edit_access_right " $q = "SELECT level, type, name FROM edit_access_right "
. "WHERE level >= 0 ORDER BY level"; . "WHERE level >= 0 ORDER BY level";
@@ -387,8 +384,10 @@ class Login
$this->default_acl_list_type[(string)$res['type']] = (int)$res['level']; $this->default_acl_list_type[(string)$res['type']] = (int)$res['level'];
} }
// write that into the session // write that into the session
$_SESSION['DEFAULT_ACL_LIST'] = $this->default_acl_list; $this->session->setMany([
$_SESSION['DEFAULT_ACL_LIST_TYPE'] = $this->default_acl_list_type; 'DEFAULT_ACL_LIST' => $this->default_acl_list,
'DEFAULT_ACL_LIST_TYPE' => $this->default_acl_list_type,
]);
$this->loginSetEditLogWriteTypeAvailable(); $this->loginSetEditLogWriteTypeAvailable();
@@ -580,7 +579,7 @@ class Login
// set path // set path
$options['locale_path'] = BASE . INCLUDES . LOCALE; $options['locale_path'] = BASE . INCLUDES . LOCALE;
} }
$_SESSION['LOCALE_PATH'] = $options['locale_path']; $this->session->set('LOCALE_PATH', $options['locale_path']);
// LANG: LOCALE // LANG: LOCALE
if (empty($options['site_locale'])) { if (empty($options['site_locale'])) {
trigger_error( trigger_error(
@@ -615,7 +614,7 @@ class Login
$options['set_domain'] = str_replace(DIRECTORY_SEPARATOR, '', CONTENT_PATH); $options['set_domain'] = str_replace(DIRECTORY_SEPARATOR, '', CONTENT_PATH);
} }
} }
$_SESSION['DEFAULT_DOMAIN'] = $options['site_domain']; $this->session->set('DEFAULT_DOMAIN', $options['site_domain']);
// LANG: ENCODING // LANG: ENCODING
if (empty($options['site_encoding'])) { if (empty($options['site_encoding'])) {
trigger_error( trigger_error(
@@ -901,9 +900,14 @@ class Login
} }
// normal user processing // normal user processing
// set class var and session var // set class var and session var
$_SESSION['EUID'] = $this->euid = (int)$res['edit_user_id']; $this->euid = (int)$res['edit_user_id'];
$_SESSION['ECUID'] = $this->ecuid = (string)$res['cuid']; $this->ecuid = (string)$res['cuid'];
$_SESSION['ECUUID'] = $this->ecuuid = (string)$res['cuuid']; $this->ecuuid = (string)$res['cuuid'];
$this->session->setMany([
'EUID' => $this->euid,
'ECUID' => $this->ecuid,
'ECUUID' => $this->ecuuid,
]);
// check if user is okay // check if user is okay
$this->loginCheckPermissions(); $this->loginCheckPermissions();
if ($this->login_error == 0) { if ($this->login_error == 0) {
@@ -916,27 +920,39 @@ class Login
. "WHERE edit_user_id = " . $this->euid; . "WHERE edit_user_id = " . $this->euid;
$this->db->dbExec($q); $this->db->dbExec($q);
} }
// now set all session vars and read page permissions $locale = $res['locale'] ?? 'en';
$_SESSION['DEBUG_ALL'] = $this->db->dbBoolean($res['debug']); $encoding = $res['encoding'] ?? 'UTF-8';
$_SESSION['DB_DEBUG'] = $this->db->dbBoolean($res['db_debug']); $this->session->setMany([
// general info for user logged in // now set all session vars and read page permissions
$_SESSION['USER_NAME'] = $res['username']; 'DEBUG_ALL' => $this->db->dbBoolean($res['debug']),
$_SESSION['ADMIN'] = $res['admin']; 'DB_DEBUG' => $this->db->dbBoolean($res['db_debug']),
$_SESSION['GROUP_NAME'] = $res['edit_group_name']; // general info for user logged in
$_SESSION['USER_ACL_LEVEL'] = $res['user_level']; 'USER_NAME' => $res['username'],
$_SESSION['USER_ACL_TYPE'] = $res['user_type']; 'ADMIN' => $res['admin'],
$_SESSION['USER_ADDITIONAL_ACL'] = Json::jsonConvertToArray($res['user_additional_acl']); 'GROUP_NAME' => $res['edit_group_name'],
$_SESSION['GROUP_ACL_LEVEL'] = $res['group_level']; 'USER_ACL_LEVEL' => $res['user_level'],
$_SESSION['GROUP_ACL_TYPE'] = $res['group_type']; 'USER_ACL_TYPE' => $res['user_type'],
$_SESSION['GROUP_ADDITIONAL_ACL'] = Json::jsonConvertToArray($res['group_additional_acl']); 'USER_ADDITIONAL_ACL' => Json::jsonConvertToArray($res['user_additional_acl']),
// deprecated TEMPLATE setting 'GROUP_ACL_LEVEL' => $res['group_level'],
$_SESSION['TEMPLATE'] = $res['template'] ? $res['template'] : ''; 'GROUP_ACL_TYPE' => $res['group_type'],
$_SESSION['HEADER_COLOR'] = !empty($res['second_header_color']) ? 'GROUP_ADDITIONAL_ACL' => Json::jsonConvertToArray($res['group_additional_acl']),
$res['second_header_color'] : // deprecated TEMPLATE setting
$res['first_header_color']; 'TEMPLATE' => $res['template'] ? $res['template'] : '',
'HEADER_COLOR' => !empty($res['second_header_color']) ?
$res['second_header_color'] :
$res['first_header_color'],
// LANGUAGE/LOCALE/ENCODING:
'LANG' => $locale,
'DEFAULT_CHARSET' => $encoding,
'DEFAULT_LOCALE' => $locale . '.' . strtoupper($encoding),
'DEFAULT_LANG' => $locale . '_' . strtolower(str_replace('-', '', $encoding))
]);
// missing # before, this is for legacy data, will be deprecated // missing # before, this is for legacy data, will be deprecated
if (preg_match("/^[\dA-Fa-f]{6,8}$/", $_SESSION['HEADER_COLOR'])) { if (
$_SESSION['HEADER_COLOR'] = '#' . $_SESSION['HEADER_COLOR']; !empty($this->session->get('HEADER_COLOR')) &&
preg_match("/^[\dA-Fa-f]{6,8}$/", $this->session->get('HEADER_COLOR'))
) {
$this->session->set('HEADER_COLOR', '#' . $this->session->get('HEADER_COLOR'));
} }
// TODO: make sure that header color is valid: // TODO: make sure that header color is valid:
// # + 6 hex // # + 6 hex
@@ -945,13 +961,6 @@ class Login
// rgb: nnn.n for each // rgb: nnn.n for each
// hsl: nnn.n for first, nnn.n% for 2nd, 3rd // hsl: nnn.n for first, nnn.n% for 2nd, 3rd
// Check\Colors::validateColor() // Check\Colors::validateColor()
// LANGUAGE/LOCALE/ENCODING:
$_SESSION['LANG'] = $res['locale'] ?? 'en';
$_SESSION['DEFAULT_CHARSET'] = $res['encoding'] ?? 'UTF-8';
$_SESSION['DEFAULT_LOCALE'] = $_SESSION['LANG']
. '.' . strtoupper($_SESSION['DEFAULT_CHARSET']);
$_SESSION['DEFAULT_LANG'] = $_SESSION['LANG'] . '_'
. strtolower(str_replace('-', '', $_SESSION['DEFAULT_CHARSET']));
// reset any login error count for this user // reset any login error count for this user
if ($res['login_error_count'] > 0) { if ($res['login_error_count'] > 0) {
$q = "UPDATE edit_user " $q = "UPDATE edit_user "
@@ -1041,8 +1050,10 @@ class Login
]; ];
} }
// write back the pages data to the output array // write back the pages data to the output array
$_SESSION['PAGES'] = $pages; $this->session->setMany([
$_SESSION['PAGES_ACL_LEVEL'] = $pages_acl; 'PAGES' => $pages,
'PAGES_ACL_LEVEL' => $pages_acl,
]);
// load the edit_access user rights // load the edit_access user rights
$q = "SELECT ea.edit_access_id, level, type, ea.name, " $q = "SELECT ea.edit_access_id, level, type, ea.name, "
. "ea.color, ea.uid, edit_default, ea.additional_acl " . "ea.color, ea.uid, edit_default, ea.additional_acl "
@@ -1054,6 +1065,7 @@ class Login
$unit_access = []; $unit_access = [];
$eauid = []; $eauid = [];
$unit_acl = []; $unit_acl = [];
$unit_uid = [];
while (is_array($res = $this->db->dbReturn($q))) { while (is_array($res = $this->db->dbReturn($q))) {
// read edit access data fields and drop them into the unit access array // read edit access data fields and drop them into the unit access array
$q_sub = "SELECT name, value " $q_sub = "SELECT name, value "
@@ -1077,16 +1089,19 @@ class Login
]; ];
// set the default unit // set the default unit
if ($res['edit_default']) { if ($res['edit_default']) {
$_SESSION['UNIT_DEFAULT'] = (int)$res['edit_access_id']; $this->session->set('UNIT_DEFAULT', (int)$res['edit_access_id']);
} }
$_SESSION['UNIT_UID'][$res['uid']] = (int)$res['edit_access_id']; $unit_uid[$res['uid']] = (int)$res['edit_access_id'];
// sub arrays for simple access // sub arrays for simple access
array_push($eauid, $res['edit_access_id']); array_push($eauid, $res['edit_access_id']);
$unit_acl[$res['edit_access_id']] = $res['level']; $unit_acl[$res['edit_access_id']] = $res['level'];
} }
$_SESSION['UNIT'] = $unit_access; $this->session->setMany([
$_SESSION['UNIT_ACL_LEVEL'] = $unit_acl; 'UNIT_UID' => $unit_uid,
$_SESSION['EAID'] = $eauid; 'UNIT' => $unit_access,
'UNIT_ACL_LEVEL' => $unit_acl,
'EAID' => $eauid,
]);
} // user has permission to THIS page } // user has permission to THIS page
} // user was not enabled or other login error } // user was not enabled or other login error
if ($this->login_error && is_array($res)) { if ($this->login_error && is_array($res)) {
@@ -1182,7 +1197,7 @@ class Login
$this->acl['base'] = (int)$_SESSION['USER_ACL_LEVEL']; $this->acl['base'] = (int)$_SESSION['USER_ACL_LEVEL'];
} }
} }
$_SESSION['BASE_ACL_LEVEL'] = $this->acl['base']; $this->session->set('BASE_ACL_LEVEL', $this->acl['base']);
// set the current page acl // set the current page acl
// start with base acl // start with base acl
@@ -1889,13 +1904,13 @@ HTML;
), ),
[ [
// row 1 // row 1
empty($username) ? $_SESSION['USER_NAME'] ?? '' : $username, empty($username) ? $this->session->get('USER_NAME') ?? '' : $username,
!empty($_SESSION['EUID']) && is_numeric($_SESSION['EUID']) ? is_numeric($this->session->get('EUID')) ?
$_SESSION['EUID'] : null, $this->session->get('EUID') : null,
!empty($_SESSION['ECUID']) && is_string($_SESSION['ECUID']) ? is_string($this->session->get('ECUID')) ?
$_SESSION['ECUID'] : null, $this->session->get('ECUID') : null,
!empty($_SESSION['ECUUID']) && Uids::validateUuuidv4($_SESSION['ECUUID']) ? !empty($this->session->get('ECUUID')) && Uids::validateUuuidv4($this->session->get('ECUUID')) ?
$_SESSION['ECUUID'] : null, $this->session->get('ECUUID') : null,
(string)$event, (string)$event,
(string)$error, (string)$error,
$data_write, $data_write,
@@ -2022,10 +2037,10 @@ HTML;
} }
} }
// if there is none, there is none, saves me POST/GET check // if there is none, there is none, saves me POST/GET check
$this->euid = array_key_exists('EUID', $_SESSION) ? (int)$_SESSION['EUID'] : 0; $this->euid = (int)($this->session->get('EUID') ?? 0);
// TODO: allow load from cuid // TODO: allow load from cuid
// $this->ecuid = array_key_exists('ECUID', $_SESSION) ? (string)$_SESSION['ECUID'] : ''; // $this->ecuid = (string)($this->session->get('ECUID') ?? '');
// $this->ecuuid = array_key_exists('ECUUID', $_SESSION) ? (string)$_SESSION['ECUUID'] : ''; // $this->ecuuid = (string)($this->session->get('ECUUID') ?? '');
// get login vars, are so, can't be changed // get login vars, are so, can't be changed
// prepare // prepare
// pass on vars to Object vars // pass on vars to Object vars
@@ -2368,8 +2383,12 @@ HTML;
$this->login_error = 103; $this->login_error = 103;
} }
// set ECUID // set ECUID
$_SESSION['ECUID'] = $this->ecuid = (string)$res['cuid']; $this->ecuid = (string)$res['cuid'];
$_SESSION['ECUUID'] = $this->ecuuid = (string)$res['cuuid']; $this->ecuuid = (string)$res['cuuid'];
$this->session->setMany([
'ECUID' => $this->ecuid,
'ECUUID' => $this->ecuuid,
]);
// if called from public, so we can check if the permissions are ok // if called from public, so we can check if the permissions are ok
return $this->permission_okay; return $this->permission_okay;
} }
@@ -2515,13 +2534,12 @@ HTML;
{ {
if ( if (
$edit_access_id !== null && $edit_access_id !== null &&
isset($_SESSION['UNIT']) && is_array($this->session->get('UNIT')) &&
is_array($_SESSION['UNIT']) && !array_key_exists($edit_access_id, $this->session->get('UNIT'))
!array_key_exists($edit_access_id, $_SESSION['UNIT'])
) { ) {
$edit_access_id = null; $edit_access_id = null;
if (is_numeric($_SESSION['UNIT_DEFAULT'])) { if (is_numeric($this->session->get('UNIT_DEFAULT'))) {
$edit_access_id = (int)$_SESSION['UNIT_DEFAULT']; $edit_access_id = (int)$this->session->get('UNIT_DEFAULT');
} }
} }
return $edit_access_id; return $edit_access_id;
@@ -2652,7 +2670,7 @@ HTML;
*/ */
public function loginGetHeaderColor(): ?string public function loginGetHeaderColor(): ?string
{ {
return $_SESSION['HEADER_COLOR'] ?? null; return $this->session->get('HEADER_COLOR');
} }
/** /**
@@ -2663,7 +2681,7 @@ HTML;
public function loginGetPages(): array public function loginGetPages(): array
{ {
return $_SESSION['PAGES'] ?? []; return $this->session->get('PAGES');
} }
/** /**

View File

@@ -380,12 +380,12 @@ class Backend
[ [
// row 1 // row 1
'', '',
!empty($_SESSION['EUID']) && is_numeric($_SESSION['EUID']) ? is_numeric($this->session->get('EUID')) ?
$_SESSION['EUID'] : null, $this->session->get('EUID') : null,
!empty($_SESSION['ECUID']) && is_string($_SESSION['ECUID']) ? is_string($this->session->get('ECUID')) ?
$_SESSION['ECUID'] : null, $this->session->get('ECUID') : null,
!empty($_SESSION['ECUUID']) && Uids::validateUuuidv4($_SESSION['ECUID']) ? !empty($this->session->get('ECUUID')) && Uids::validateUuuidv4($this->session->get('ECUID')) ?
$_SESSION['ECUID'] : null, $this->session->get('ECUID') : null,
(string)$event, (string)$event,
'', '',
$data_write, $data_write,
@@ -468,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 = [];
} }

View File

@@ -97,6 +97,23 @@ class Session
return true; return true;
} }
/**
* 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) // MARK: init session (on class start)
/** /**
@@ -162,6 +179,9 @@ class Session
public function restartSession(): bool public function restartSession(): bool
{ {
if (!$this->checkActiveSession()) { if (!$this->checkActiveSession()) {
if (empty($this->session_name)) {
throw new \RuntimeException('[SESSION] Cannot restart session without a session name', 1);
}
$this->startSessionCall(); $this->startSessionCall();
return true; return true;
} }
@@ -235,6 +255,21 @@ class Session
return \CoreLibs\Get\System::checkCLI(); 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 // MARK: write close session
/** /**
@@ -256,13 +291,18 @@ class Session
* 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')
@@ -282,24 +322,12 @@ class Session
$params['httponly'] $params['httponly']
); );
} }
// unset internal vars
$this->session_name = '';
$this->session_id = '';
return session_destroy(); return session_destroy();
} }
/**
* 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: _SESSION set/unset methods // MARK: _SESSION set/unset methods
/** /**
@@ -307,11 +335,14 @@ class Session
* *
* @return void * @return void
*/ */
public function unsetAll(): void public function clear(): void
{ {
$this->restartSession(); $this->restartSession();
foreach (array_keys($_SESSION ?? []) as $name) { if (!session_unset()) {
unset($_SESSION[$name]); throw new \RuntimeException('[SESSION] Cannot unset session vars', 1);
}
if (!empty($_SESSION)) {
$_SESSION = [];
} }
$this->closeSessionCall(); $this->closeSessionCall();
} }
@@ -319,35 +350,64 @@ class Session
/** /**
* 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 void * @return void
*/ */
public function set(string|int $name, mixed $value): void public function set(string $name, mixed $value): void
{ {
$this->checkValidSessionEntryKey($name);
$this->restartSession(); $this->restartSession();
$_SESSION[$name] = $value; $_SESSION[$name] = $value;
$this->closeSessionCall(); $this->closeSessionCall();
} }
/**
* 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
*/
public function setMany(array $set): void
{
$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 get(string|int $name): mixed public function get(string $name): mixed
{ {
return $_SESSION[$name] ?? null; 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 isset(string|int $name): bool public function isset(string $name): bool
{ {
return isset($_SESSION[$name]); return isset($_SESSION[$name]);
} }
@@ -355,10 +415,10 @@ 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 void * @return void
*/ */
public function unset(string|int $name): void public function unset(string $name): void
{ {
if (!isset($_SESSION[$name])) { if (!isset($_SESSION[$name])) {
return; return;
@@ -368,65 +428,21 @@ class Session
$this->closeSessionCall(); $this->closeSessionCall();
} }
// MARK: [DEPRECATED] __set/__get magic methods
// ->var = value;
/** /**
* Undocumented function * reset many session entry
* *
* @param string|int $name * @param array<string> $set list of session keys to reset
* @param mixed $value
* @return void * @return void
* @deprecated use ->set()
*/ */
public function __set(string|int $name, mixed $value): void public function unsetMany(array $set): void
{ {
$this->restartSession(); $this->restartSession();
$_SESSION[$name] = $value; foreach ($set as $key) {
$this->closeSessionCall(); if (!isset($_SESSION[$key])) {
} continue;
}
/** unset($_SESSION[$key]);
* Undocumented function
*
* @param string|int $name
* @return mixed If name is not found, it will return null
* @deprecated use ->get()
*/
public function __get(string|int $name): mixed
{
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
} }
return null;
}
/**
* Undocumented function
*
* @param string|int $name
* @return bool
* @deprecated use ->isset()
*/
public function __isset(string|int $name): bool
{
return isset($_SESSION[$name]);
}
/**
* Undocumented function
*
* @param string|int $name
* @return void
* @deprecated use ->unset()
*/
public function __unset(string|int $name): void
{
if (!isset($_SESSION[$name])) {
return;
}
$this->restartSession();
unset($_SESSION[$name]);
$this->closeSessionCall(); $this->closeSessionCall();
} }
} }

View File

@@ -1332,6 +1332,7 @@ class IO
*/ */
private function __dbCheckQueryParams(string $query, array $params): bool private function __dbCheckQueryParams(string $query, array $params): bool
{ {
// $this->log->debug('DB QUERY PARAMS REGEX', ConvertPlaceholder::REGEX_LOOKUP_PLACEHOLDERS);
$placeholder_count = $this->__dbCountQueryParams($query); $placeholder_count = $this->__dbCountQueryParams($query);
$params_count = count($params); $params_count = count($params);
if ($params_count != $placeholder_count) { if ($params_count != $placeholder_count) {

View File

@@ -14,8 +14,19 @@ namespace CoreLibs\DB\Support;
class ConvertPlaceholder class ConvertPlaceholder
{ {
/** @var string split regex */ // NOTE for missing: range */+ are not iplemented in the regex below, but - is for now
private const PATTERN_QUERY_SPLIT = '[(<>=,?-]|->|->>|#>|#>>|@>|<@|\?\|\?\&|\|\||#-'; // NOTE some combinations are allowed, but the query will fail before this
/** @var string split regex, entries before $ group */
private const PATTERN_QUERY_SPLIT =
',|' // for ',' mostly in INSERT
. '[(<>=]|' // general set for (, <, >, = in any query with any combination
. '(?:[\(,]\s*\-\-[\s\w]*)\r?\n|' // a comment that starts after a ( or ,
. '\^@|' // text search for start from text with ^@
. '\|\||' // concats two elements
. '&&|' // array overlap
. '\-\|\-|' // range overlap
. '[^-]-{1}|' // single -, used in JSON too
. '->|->>|#>|#>>|@>|<@|@@|@\?|\?{1}|\?\||\?&|#-'; //JSON searches, Array searchs, etc
/** @var string the main regex including the pattern query split */ /** @var string the main regex including the pattern query split */
private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:\?\?|' . self::PATTERN_QUERY_SPLIT . ')\s*'; private const PATTERN_ELEMENT = '(?:\'.*?\')?\s*(?:\?\?|' . self::PATTERN_QUERY_SPLIT . ')\s*';
/** @var string parts to ignore in the SQL */ /** @var string parts to ignore in the SQL */

View File

@@ -2,7 +2,7 @@
/* /*
* sets a form token in the _SESSION variable * sets a form token in the _SESSION variable
* session must be started for this to work * session must be started and running for this to work
*/ */
declare(strict_types=1); declare(strict_types=1);