diff --git a/4dev/tests/Create/CoreLibsCreateSessionTest.php b/4dev/tests/Create/CoreLibsCreateSessionTest.php index f9c89109..d3a4f735 100644 --- a/4dev/tests/Create/CoreLibsCreateSessionTest.php +++ b/4dev/tests/Create/CoreLibsCreateSessionTest.php @@ -22,7 +22,6 @@ final class CoreLibsCreateSessionTest extends TestCase public function sessionProvider(): array { // 0: session name as parameter or for GLOBAL value - // 1: type p: parameter, g: global, d: php.ini default // 2: mock data as array // checkCliStatus: true/false, // getSessionStatus: PHP_SESSION_DISABLED for abort, @@ -31,13 +30,10 @@ final class CoreLibsCreateSessionTest extends TestCase // checkActiveSession: true/false, [1st call, 2nd call] // getSessionId: string or false // 3: exepcted name (session)] - // 4: Exception thrown on error - // 5: exception code, null for none - // 6: expected error string + // 4: auto write close flag return [ 'session parameter' => [ 'sessionNameParameter', - 'p', [ 'checkCliStatus' => false, 'getSessionStatus' => PHP_SESSION_NONE, @@ -47,12 +43,9 @@ final class CoreLibsCreateSessionTest extends TestCase ], 'sessionNameParameter', null, - null, - '', ], 'session globals' => [ 'sessionNameGlobals', - 'g', [ 'checkCliStatus' => false, 'getSessionStatus' => PHP_SESSION_NONE, @@ -61,13 +54,10 @@ final class CoreLibsCreateSessionTest extends TestCase 'getSessionId' => '1234abcd4567' ], 'sessionNameGlobals', - null, - null, - '', + false, ], - 'session name default' => [ - '', - 'd', + 'auto write close' => [ + 'sessionNameAutoWriteClose', [ 'checkCliStatus' => false, 'getSessionStatus' => PHP_SESSION_NONE, @@ -75,109 +65,8 @@ final class CoreLibsCreateSessionTest extends TestCase 'checkActiveSession' => [false, true], 'getSessionId' => '1234abcd4567' ], - '', - null, - null, - '', - ], - // error checks - // 1: we are in cli - 'on cli error' => [ - '', - 'd', - [ - 'checkCliStatus' => true, - 'getSessionStatus' => PHP_SESSION_NONE, - 'setSessionName' => true, - 'checkActiveSession' => [false, true], - 'getSessionId' => '1234abcd4567' - ], - '', - 'RuntimeException', - 1, - '[SESSION] No sessions in php cli' - ], - // 2: session disabled - 'session disabled error' => [ - '', - 'd', - [ - 'checkCliStatus' => false, - 'getSessionStatus' => PHP_SESSION_DISABLED, - 'setSessionName' => true, - 'checkActiveSession' => [false, true], - 'getSessionId' => '1234abcd4567' - ], - '', - 'RuntimeException', - 2, - '[SESSION] Sessions are disabled' - ], - // 3: invalid session name: string - 'invalid name chars error' => [ - '1invalid$session#;', - 'p', - [ - 'checkCliStatus' => false, - 'getSessionStatus' => PHP_SESSION_NONE, - 'setSessionName' => false, - 'checkActiveSession' => [false, true], - 'getSessionId' => '1234abcd4567' - ], - '', - 'UnexpectedValueException', - 3, - '[SESSION] Invalid session name: 1invalid$session#;' - ], - // 3: invalid session name: only numbers - 'invalid name numbers only error' => [ - '123', - 'p', - [ - 'checkCliStatus' => false, - 'getSessionStatus' => PHP_SESSION_NONE, - 'setSessionName' => false, - 'checkActiveSession' => [false, true], - 'getSessionId' => '1234abcd4567' - ], - '', - 'UnexpectedValueException', - 3, - '[SESSION] Invalid session name: 123' - ], - // 3: invalid session name: invalid name short - // 3: invalid session name: too long (128) - // 4: failed to start session (2nd false on check active session) - 'invalid name numbers only error' => [ - '', - 'd', - [ - 'checkCliStatus' => false, - 'getSessionStatus' => PHP_SESSION_NONE, - 'setSessionName' => true, - 'checkActiveSession' => [false, false], - 'getSessionId' => '1234abcd4567' - ], - '', - 'RuntimeException', - 4, - '[SESSION] Failed to activate session' - ], - // 5: get session id return false - 'invalid name numbers only error' => [ - '', - 'd', - [ - 'checkCliStatus' => false, - 'getSessionStatus' => PHP_SESSION_NONE, - 'setSessionName' => true, - 'checkActiveSession' => [false, true], - 'getSessionId' => false - ], - '', - 'UnexpectedValueException', - 5, - '[SESSION] getSessionId did not return a session id' + 'sessionNameAutoWriteClose', + true, ], ]; } @@ -190,32 +79,23 @@ final class CoreLibsCreateSessionTest extends TestCase * @testdox startSession $input name for $type will be $expected (error: $expected_error) [$_dataName] * * @param string $input - * @param string $type * @param array $mock_data * @param string $expected - * @param string|null $exception - * @param string $expected_error * @return void */ public function testStartSession( string $input, - string $type, array $mock_data, string $expected, - ?string $exception, - ?int $exception_code, - string $expected_error + ?bool $auto_write_close, ): void { - // override expected - if ($type == 'd') { - $expected = ini_get('session.name'); - } /** @var \CoreLibs\Create\Session&MockObject $session_mock */ $session_mock = $this->createPartialMock( \CoreLibs\Create\Session::class, [ - 'checkCliStatus', 'getSessionStatus', 'checkActiveSession', - 'setSessionName', 'startSessionCall', 'getSessionId', + 'checkCliStatus', + 'getSessionStatus', 'checkActiveSession', + 'getSessionId', 'getSessionName' ] ); @@ -234,12 +114,8 @@ final class CoreLibsCreateSessionTest extends TestCase $mock_data['checkActiveSession'][0], $mock_data['checkActiveSession'][1], ); - // dummy set for session name - $session_mock->method('setSessionName')->with($input)->willReturn($mock_data['setSessionName']); // set session name & return bsed on request data $session_mock->method('getSessionName')->willReturn($expected); - // will not return anything - $session_mock->method('startSessionCall'); // in test case only return string // false: will return false $session_mock->method('getSessionId')->willReturn($mock_data['getSessionId']); @@ -247,25 +123,7 @@ final class CoreLibsCreateSessionTest extends TestCase // regex for session id $ression_id_regex = "/^\w+$/"; - if ($exception !== null) { - $this->expectException($exception); - $this->expectExceptionCode($exception_code); - } - - unset($GLOBALS['SET_SESSION_NAME']); - $session_id = ''; - switch ($type) { - case 'p': - $session_id = $session_mock->startSession($input); - break; - case 'g': - $GLOBALS['SET_SESSION_NAME'] = $input; - $session_id = $session_mock->startSession(); - break; - case 'd': - $session_id = $session_mock->startSession(); - break; - } + $session_id = $session_mock->getSessionId(); // asert checks if (!empty($session_id)) { $this->assertMatchesRegularExpression( @@ -284,6 +142,73 @@ final class CoreLibsCreateSessionTest extends TestCase } } + /** + * Undocumented function + * + * @return array + */ + public function providerSessionException(): array + { + return [ + 'not cli' => [ + 'TEST_EXCEPTION', + \RuntimeException::class, + 1, + '/^\[SESSION\] No sessions in php cli$/', + ], + /* 'session disabled ' => [ + 'TEST_EXCEPTION', + \RuntimeException::class, + 2, + '/^\[SESSION\] Sessions are disabled/' + ], + 'invalid session name' => [ + '--#as^-292p-', + \UnexpectedValueException::class, + 3, + '/^\[SESSION\] Invalid session name: /' + ], + 'failed to activate session' => [ + 'TEST_EXCEPTION', + \RuntimeException::class, + 4, + '/^\[SESSION\] Failed to activate session/' + ], + 'not a valid session id returned' => [ + \UnexpectedValueException::class, + 5, + '/^\[SESSION\] getSessionId did not return a session id/' + ], */ + ]; + } + + /** + * exception checks + * + * @covers ::initSession + * @dataProvider providerSessionException + * @testdox create session $session_name with exception $exception ($exception_code) [$_dataName] + * + * @param string $session_name + * @param string $exception + * @param int $exception_code + * @param string $expected_error + * @return void + */ + public function testSessionException( + string $session_name, + string $exception, + int $exception_code, + string $expected_error, + ): void { + // + // throws only on new Object creation + $this->expectException($exception); + $this->expectExceptionCode($exception_code); + $this->expectExceptionMessageMatches($expected_error); + new \CoreLibs\Create\Session($session_name); + } + /** * provider for session name check * @@ -369,6 +294,8 @@ final class CoreLibsCreateSessionTest extends TestCase ]; } + // NOTE: with auto start session, we cannot test this in the command line + /** * method call test * @@ -384,74 +311,32 @@ final class CoreLibsCreateSessionTest extends TestCase * @param mixed $expected * @return void */ - public function testMethodSetGet($name, $input, $expected): void +/* public function testMethodSetGet($name, $input, $expected): void { - $session = new \CoreLibs\Create\Session(); - $session->setS($name, $input); + $session = new \CoreLibs\Create\Session('TEST_METHOD'); + $session->set($name, $input); $this->assertEquals( $expected, - $session->getS($name), + $session->get($name), 'method set assert' ); // isset true $this->assertTrue( - $session->issetS($name), + $session->isset($name), 'method isset assert ok' ); - $session->unsetS($name); + $session->unset($name); $this->assertEquals( '', - $session->getS($name), + $session->get($name), 'method unset assert' ); // iset false $this->assertFalse( - $session->issetS($name), + $session->isset($name), 'method isset assert false' ); - } - - /** - * magic call test - * - * @covers ::__set - * @covers ::__get - * @covers ::__isset - * @covers ::__unset - * @dataProvider sessionDataProvider - * @testdox __set/__get/__iseet/__unset $name with $input is $expected [$_dataName] - * - * @param string|int $name - * @param mixed $input - * @param mixed $expected - * @return void - */ - public function testMagicSetGet($name, $input, $expected): void - { - $session = new \CoreLibs\Create\Session(); - $session->$name = $input; - $this->assertEquals( - $expected, - $session->$name, - 'magic set assert' - ); - // isset true - $this->assertTrue( - isset($session->$name), - 'magic isset assert ok' - ); - unset($session->$name); - $this->assertEquals( - '', - $session->$name, - 'magic unset assert' - ); - // isset true - $this->assertFalse( - isset($session->$name), - 'magic isset assert false' - ); - } + } */ /** * unset all test @@ -461,33 +346,33 @@ final class CoreLibsCreateSessionTest extends TestCase * * @return void */ - public function testUnsetAll(): void +/* public function testUnsetAll(): void { $test_values = [ 'foo' => 'abc', 'bar' => '123' ]; - $session = new \CoreLibs\Create\Session(); + $session = new \CoreLibs\Create\Session('TEST_UNSET'); foreach ($test_values as $name => $value) { - $session->setS($name, $value); + $session->set($name, $value); // confirm set $this->assertEquals( $value, - $session->getS($name), + $session->get($name), 'set assert: ' . $name ); } // unset all - $session->unsetAllS(); + $session->unsetAll(); // check unset foreach (array_keys($test_values) as $name) { $this->assertEquals( '', - $session->getS($name), + $session->get($name), 'unsert assert: ' . $name ); } - } + } */ } // __END__ diff --git a/www/admin/class_test.db.php b/www/admin/class_test.db.php index 6212c768..1326a023 100644 --- a/www/admin/class_test.db.php +++ b/www/admin/class_test.db.php @@ -228,7 +228,7 @@ print "RETURN ROW PARAMS: " . print_r( $db->dbPrepare("ins_test_foo", "INSERT INTO test_foo (test) VALUES ($1) RETURNING test"); $status = $db->dbExecute("ins_test_foo", ['BAR TEST ' . time()]); print "PREPARE INSERT[ins_test_foo] STATUS: " . Support::printToString($status) . " |
" - . "QUERY: " . $db->dbGetPrepareCursorValue('ins_test_foo', 'query') . " |
" + . "QUERY: " . Support::printToString($db->dbGetPrepareCursorValue('ins_test_foo', 'query')) . " |
" . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "
"; @@ -255,7 +255,7 @@ SQL; $db->dbPrepare("ins_test_foo_eom", $query); $status = $db->dbExecute("ins_test_foo_eom", ['EOM BAR TEST ' . time()]); print "EOM STRING PREPARE INSERT[ins_test_foo_eom] STATUS: " . Support::printToString($status) . " |
" - . "QUERY: " . $db->dbGetPrepareCursorValue('ins_test_foo_eom', 'query') . " |
" + . "QUERY: " . Support::printToString($db->dbGetPrepareCursorValue('ins_test_foo_eom', 'query')) . " |
" . "PRIMARY KEY: " . Support::printToString($db->dbGetInsertPK()) . " | " . "RETURNING EXT: " . print_r($db->dbGetReturningExt(), true) . " | " . "RETURNING RETURN: " . print_r($db->dbGetReturningArray(), true) . "
"; diff --git a/www/admin/class_test.session.php b/www/admin/class_test.session.php index b0a9ba46..49f5b3ee 100644 --- a/www/admin/class_test.session.php +++ b/www/admin/class_test.session.php @@ -46,7 +46,6 @@ $log = new CoreLibs\Logging\Logging([ 'log_per_date' => true, ]); use CoreLibs\Create\Session; -$session = new Session(); $PAGE_NAME = 'TEST CLASS: SESSION'; print ""; @@ -56,50 +55,30 @@ print '
Class Test Master
'; print '

' . $PAGE_NAME . '

'; $session_name = 'class-test-session'; +print "Valid session name static check for '" . $session_name . "': " + . \CoreLibs\Debug\Support::prBl(Session::checkValidSessionName($session_name)) . "
"; $var = 'foo'; $value = 'bar'; +$session = new Session($session_name); foreach (['123', '123-123', '123abc'] as $_session_name) { - print "[UNSET] Session Name valid for " . $_session_name . ": " + print "[UNSET] Session Name valid for '" . $_session_name . "': " . ($session->checkValidSessionName($_session_name) ? 'Valid' : 'Invalid') . "
"; } echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "
"; -print "[UNSET] Current session id: " . $session->getSessionId() . "
"; -print "[UNSET] Current session name: " . $session->getSessionName() . "
"; -print "[UNSET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "
"; -print "[UNSET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "
"; -if (isset($_SESSION)) { - print "[UNSET] _SESSION is: set
"; -} else { - print "[UNSET] _SESSION is: not set
"; -} -# -print "[UNSET] To set session name valid: " - . ($session->checkValidSessionName($session_name) ? 'Valid' : 'Invalid') . "
"; -try { - $session_id = $session->startSession($session_name); - print "[SET] Current session id: " . $session_id . "
"; -} catch (\Exception $e) { - print "[FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; -} -// set again -try { - $session_id = $session->startSession($session_name); - print "[2 SET] Current session id: " . $session_id . "
"; -} catch (\Exception $e) { - print "[2 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; -} print "[SET] Current session id: " . $session->getSessionId() . "
"; print "[SET] Current session name: " . $session->getSessionName() . "
"; print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "
"; +print "[SET] Current session auto write close: " . ($session->checkAutoWriteClose() ? 'Yes' : 'No') . "
"; print "[SET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "
"; if (isset($_SESSION)) { print "[SET] _SESSION is: set
"; } else { print "[SET] _SESSION is: not set
"; } +# if (!isset($_SESSION['counter'])) { $_SESSION['counter'] = 0; } @@ -111,12 +90,12 @@ print "[READ] Confirm " . $var . " is " . $value . ": " . (($_SESSION[$var] ?? '') == $value ? 'Matching' : 'Not matching') . "
"; // test set wrappers methods -$session->setS('setwrap', 'YES, method set _SESSION var'); -print "[READ WRAP] A setwrap: " . $session->getS('setwrap') . "
"; -print "[READ WRAP] Isset: " . ($session->issetS('setwrap') ? 'Yes' : 'No') . "
"; -$session->unsetS('setwrap'); -print "[READ WRAP] unset setwrap: " . $session->getS('setwrap') . "
"; -print "[READ WRAP] unset Isset: " . ($session->issetS('setwrap') ? 'Yes' : 'No') . "
"; +$session->set('setwrap', 'YES, method set _SESSION var'); +print "[READ WRAP] A setwrap: " . $session->get('setwrap') . "
"; +print "[READ WRAP] Isset: " . ($session->isset('setwrap') ? 'Yes' : 'No') . "
"; +$session->unset('setwrap'); +print "[READ WRAP] unset setwrap: " . $session->get('setwrap') . "
"; +print "[READ WRAP] unset Isset: " . ($session->isset('setwrap') ? 'Yes' : 'No') . "
"; // test __get/__set $session->setwrap = 'YES, magic set _SESSION var'; /** @phpstan-ignore-line GET/SETTER */ print "[READ MAGIC] A setwrap: " . ($session->setwrap ?? '') . "
"; @@ -125,15 +104,16 @@ unset($session->setwrap); print "[READ MAGIC] unset setwrap: " . ($session->setwrap ?? '') . "
"; print "[READ MAGIC] unset Isset: " . (isset($session->setwrap) ? 'Yes' : 'No') . "
"; +print "
"; // differnt session name $session_name = 'class-test-session-ALT'; try { - $session_id = $session->startSession($session_name); - print "[3 SET] Current session id: " . $session_id . "
"; + $session_alt = new Session($session_name); + print "[3 SET] Current session id: " . $session_alt->getSessionId() . "
"; + print "[SET AGAIN] Current session id: " . $session_alt->getSessionId() . "
"; } catch (\Exception $e) { - print "[3 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; + print "[3 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "

"; } -print "[SET AGAIN] Current session id: " . $session->getSessionId() . "
"; print "[ALL SESSION]: " . \CoreLibs\Debug\Support::printAr($_SESSION) . "
"; @@ -141,32 +121,39 @@ print "[ALL SESSION]: " . \CoreLibs\Debug\Support::printAr($_SESSION) . "
"; $session->writeClose(); // will never be written $_SESSION['will_never_be_written'] = 'empty'; +// auto open session if closed to write +$session->set('auto_write_session', 'Some value'); +// restart session +$session->restartSession(); +$_SESSION['this_will_be_written'] = 'not empty'; -// open again +// open again with same name $session_name = 'class-test-session'; try { - $session_id = $session->startSession($session_name); - print "[4 SET] Current session id: " . $session_id . "
"; + $session_alt = new Session($session_name, auto_write_close:true); + print "[4 SET] Current session id: " . $session_alt->getSessionId() . "
"; + print "[4 SET] Current session auto write close: " . ($session_alt->checkAutoWriteClose() ? 'Yes' : 'No') . "
"; + print "[START AGAIN] Current session id: " . $session_alt->getSessionId() . "
"; + $session_alt->set('alt_write_auto_close', 'set auto'); + // below is deprecated + // $session_alt->do_not_do_this = 'foo bar auto set'; } catch (\Exception $e) { - print "[4 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; + print "[4 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "

"; } -print "[START AGAIN] Current session id: " . $session->getSessionId() . "
"; $_SESSION['will_be_written_again'] = 'Full'; +print "[ALL SESSION]: " . \CoreLibs\Debug\Support::printAr($_SESSION) . "
"; + // close session $session->writeClose(); // invalid $session_name = '123'; try { - $session_id = $session->startSession($session_name); - print "[5 SET] Current session id: " . $session_id . "
"; + $session_bad = new Session($session_name); + print "[5 SET] Current session id: " . $session_bad->getSessionId() . "
"; } catch (\Exception $e) { - print "[5 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; + print "[5 FAILED] Session start failed:
" . $e->getMessage() . "
" . $e . "

"; } -print "[BAD NAME] Current session id: " . $session->getSessionId() . "
"; -print "[BAD NAME] Current session name: " . $session->getSessionName() . "
"; -print "[BAD NAME] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "
"; -print "[BAD NAME] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "
"; print ""; diff --git a/www/admin/class_test.session.read.php b/www/admin/class_test.session.read.php index 09b2330f..b2e6e8e3 100644 --- a/www/admin/class_test.session.read.php +++ b/www/admin/class_test.session.read.php @@ -46,7 +46,6 @@ $log = new CoreLibs\Logging\Logging([ 'log_per_date' => true, ]); use CoreLibs\Create\Session; -$session = new Session(); $PAGE_NAME = 'TEST CLASS: SESSION (READ)'; print ""; @@ -56,32 +55,22 @@ print '
Class Test Master
'; print '

' . $PAGE_NAME . '

'; $session_name = 'class-test-session'; +$session = new Session($session_name); // $session_name = ''; $var = 'foo'; $value = 'bar'; echo "Global session name: " . ($GLOBALS['SET_SESSION_NAME'] ?? '-') . "
"; -print "[UNSET] Current session id: " . $session->getSessionId() . "
"; -print "[UNSET] Current session name: " . $session->getSessionName() . "
"; -print "[UNSET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "
"; -print "[UNSET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "
"; +print "[SET] Current session id: " . $session->getSessionId() . "
"; +print "[SET] Current session name: " . $session->getSessionName() . "
"; +print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "
"; +print "[SET] Current session status: " . getSessionStatusString($session->getSessionStatus()) . "
"; print "[READ] " . $var . ": " . ($_SESSION[$var] ?? '{UNSET}') . "
"; -// start -try { - $session_id = $session->startSession($session_name); - print "[1] Current session id: " . $session_id . "
"; -} catch (\Exception $e) { - print "[1] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; -} + // set again -try { - $session_id = $session->startSession($session_name); - print "[2] Current session id: " . $session_id . "
"; -} catch (\Exception $e) { - print "[2] Session start failed:
" . $e->getMessage() . "
" . $e . "
"; -} +print "[2] Restarted session: " . \CoreLibs\Debug\Support::prBl($session->restartSession()) . "
"; print "[SET] Current session id: " . $session->getSessionId() . "
"; print "[SET] Current session name: " . $session->getSessionName() . "
"; print "[SET] Current session active: " . ($session->checkActiveSession() ? 'Yes' : 'No') . "
"; diff --git a/www/lib/CoreLibs/ACL/Login.php b/www/lib/CoreLibs/ACL/Login.php index 48a73282..fa8cd99f 100644 --- a/www/lib/CoreLibs/ACL/Login.php +++ b/www/lib/CoreLibs/ACL/Login.php @@ -1913,7 +1913,7 @@ HTML; $_SERVER['HTTP_ACCEPT'] ?? null, $_SERVER['HTTP_ACCEPT_CHARSET'] ?? null, $_SERVER['HTTP_ACCEPT_ENCODING'] ?? null, - $this->session->getSessionId() !== false ? + $this->session->getSessionId() !== '' ? $this->session->getSessionId() : null, // row 4 $action_set['action'] ?? null, diff --git a/www/lib/CoreLibs/Admin/Backend.php b/www/lib/CoreLibs/Admin/Backend.php index 1c088cae..82d36807 100644 --- a/www/lib/CoreLibs/Admin/Backend.php +++ b/www/lib/CoreLibs/Admin/Backend.php @@ -403,7 +403,7 @@ class Backend $_SERVER['HTTP_ACCEPT'] ?? '', $_SERVER['HTTP_ACCEPT_CHARSET'] ?? '', $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', - $this->session->getSessionId() !== false ? + $this->session->getSessionId() !== '' ? $this->session->getSessionId() : null, // row 4 $this->action ?? '', diff --git a/www/lib/CoreLibs/Create/Session.php b/www/lib/CoreLibs/Create/Session.php index ca3607e6..1bf910f5 100644 --- a/www/lib/CoreLibs/Create/Session.php +++ b/www/lib/CoreLibs/Create/Session.php @@ -15,19 +15,27 @@ namespace CoreLibs\Create; class Session { + /** @var string current session name */ + private string $session_name = ''; + /** @var string current session id */ + private string $session_id = ''; + /** @var bool flag auto write close */ + private bool $auto_write_close = false; + /** * init a session, if array is empty or array does not have session_name set * then no auto init is run * * @param string $session_name if set and not empty, will start session */ - public function __construct(string $session_name = '') + public function __construct(string $session_name, bool $auto_write_close = false) { - if (!empty($session_name)) { - $this->startSession($session_name); - } + $this->initSession($session_name); + $this->auto_write_close = $auto_write_close; } + // MARK: private methods + /** * Start session * startSession should be called for complete check @@ -36,36 +44,32 @@ class Session * * @return void */ - protected function startSessionCall(): void + private function startSessionCall(): void { session_start(); } /** - * check if we are in CLI, we set this, so we can mock this - * Not this is just a wrapper for the static System::checkCLI call + * get current set session id or false if none started * - * @return bool True if we are in a CLI enviroment, or false for everything else + * @return string|false */ - public function checkCliStatus(): bool + public function getSessionIdCall(): string|false { - return \CoreLibs\Get\System::checkCLI(); + return session_id(); } /** - * Set session name call. If not valid session name, will return false + * automatically closes a session if the auto write close flag is set * - * @param string $session_name A valid string for session name - * @return bool True if session name is valid, - * False if not + * @return bool */ - public function setSessionName(string $session_name): bool + private function closeSessionCall(): bool { - if (!$this->checkValidSessionName($session_name)) { - return false; + if ($this->auto_write_close) { + return $this->writeClose(); } - session_name($session_name); - return true; + return false; } /** @@ -93,16 +97,18 @@ class Session return true; } + // MARK: init session (on class start) + /** - * start session with given session name if set + * stinitart session with given session name if set * aborts on command line or if sessions are not enabled * also aborts if session cannot be started * On sucess returns the session id * - * @param string|null $session_name - * @return string|bool + * @param string $session_name + * @return void */ - public function startSession(?string $session_name = null): string|bool + private function initSession(string $session_name): void { // we can't start sessions on command line if ($this->checkCliStatus()) { @@ -115,39 +121,82 @@ class Session // session_status // initial the session if there is no session running already if (!$this->checkActiveSession()) { - // if session name is emtpy, check if there is a global set - // this is a deprecated fallback - $session_name = $session_name ?? $GLOBALS['SET_SESSION_NAME'] ?? ''; - // DEPRECTED: constant SET_SESSION_NAME is no longer used - // if set, set special session name - if (!empty($session_name)) { - // invalid session name, abort - if (!$this->checkValidSessionName($session_name)) { - throw new \UnexpectedValueException('[SESSION] Invalid session name: ' . $session_name, 3); - } - $this->setSessionName($session_name); + // invalid session name, abort + if (!$this->checkValidSessionName($session_name)) { + throw new \UnexpectedValueException('[SESSION] Invalid session name: ' . $this->session_name, 3); } + // set session name + $this->session_name = $session_name; + session_name($this->session_name); // start session $this->startSessionCall(); + // if we faild to start the session + if (!$this->checkActiveSession()) { + throw new \RuntimeException('[SESSION] Failed to activate session', 5); + } + } elseif ($session_name != $this->getSessionName()) { + throw new \UnexpectedValueException( + '[SESSION] Another session exists with a different name: ' . $this->getSessionName(), + 4 + ); } - // if we still have no active session + // check session id + if (false === ($session_id = $this->getSessionIdCall())) { + throw new \UnexpectedValueException('[SESSION] getSessionId did not return a session id', 6); + } + // set session id + $this->session_id = $session_id; + // if flagged auto close, write close session + if ($this->auto_write_close) { + $this->writeClose(); + } + } + + // MARK: public set/get status + + /** + * start session, will only run after initSession + * + * @return bool True if started, False if alrady running + */ + public function restartSession(): bool + { if (!$this->checkActiveSession()) { - throw new \RuntimeException('[SESSION] Failed to activate session', 4); + $this->startSessionCall(); + return true; } - if (false === ($session_id = $this->getSessionId())) { - throw new \UnexpectedValueException('[SESSION] getSessionId did not return a session id', 5); - } - return $session_id; + return false; } /** - * get current set session id or false if none started + * current set session id * - * @return string|bool + * @return string */ - public function getSessionId(): string|bool + public function getSessionId(): string { - return session_id(); + return $this->session_id; + } + + /** + * set the auto write close flag + * + * @param bool $flag + * @return void + */ + public function setAutoWriteClose(bool $flag): void + { + $this->auto_write_close = $flag; + } + + /** + * return the auto write close flag + * + * @return bool + */ + public function checkAutoWriteClose(): bool + { + return $this->auto_write_close; } /** @@ -175,6 +224,19 @@ class Session } } + /** + * check if we are in CLI, we set this, so we can mock this + * Not this is just a wrapper for the static System::checkCLI call + * + * @return bool True if we are in a CLI enviroment, or false for everything else + */ + public function checkCliStatus(): bool + { + return \CoreLibs\Get\System::checkCLI(); + } + + // MARK: write close session + /** * unlock the session file, so concurrent AJAX requests can be done * NOTE: after this has been called, no changes in _SESSION will be stored @@ -188,6 +250,8 @@ class Session return session_write_close(); } + // MARK: session close and clean up + /** * Proper destroy a session * - unset the _SESSION array @@ -236,18 +300,20 @@ class Session return session_status(); } - // _SESSION set/unset methods + // MARK: _SESSION set/unset methods /** * unset all _SESSION entries * * @return void */ - public function unsetAllS(): void + public function unsetAll(): void { + $this->restartSession(); foreach (array_keys($_SESSION ?? []) as $name) { unset($_SESSION[$name]); } + $this->closeSessionCall(); } /** @@ -257,9 +323,11 @@ class Session * @param mixed $value value to set (can be anything) * @return void */ - public function setS(string|int $name, mixed $value): void + public function set(string|int $name, mixed $value): void { + $this->restartSession(); $_SESSION[$name] = $value; + $this->closeSessionCall(); } /** @@ -268,9 +336,9 @@ class Session * @param string|int $name value key to get from _SESSION * @return mixed value stored in _SESSION */ - public function getS(string|int $name): mixed + public function get(string|int $name): mixed { - return $_SESSION[$name] ?? ''; + return $_SESSION[$name] ?? null; } /** @@ -279,7 +347,7 @@ class Session * @param string|int $name Name to check for * @return bool True for set, False fornot set */ - public function issetS(string|int $name): bool + public function isset(string|int $name): bool { return isset($_SESSION[$name]); } @@ -290,14 +358,17 @@ class Session * @param string|int $name _SESSION key name to remove * @return void */ - public function unsetS(string|int $name): void + public function unset(string|int $name): void { - if (isset($_SESSION[$name])) { - unset($_SESSION[$name]); + if (!isset($_SESSION[$name])) { + return; } + $this->restartSession(); + unset($_SESSION[$name]); + $this->closeSessionCall(); } - // set/get below + // MARK: [DEPRECATED] __set/__get magic methods // ->var = value; /** @@ -306,10 +377,13 @@ class Session * @param string|int $name * @param mixed $value * @return void + * @deprecated use ->set() */ public function __set(string|int $name, mixed $value): void { + $this->restartSession(); $_SESSION[$name] = $value; + $this->closeSessionCall(); } /** @@ -317,6 +391,7 @@ class Session * * @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 { @@ -331,6 +406,7 @@ class Session * * @param string|int $name * @return bool + * @deprecated use ->isset() */ public function __isset(string|int $name): bool { @@ -342,12 +418,16 @@ class Session * * @param string|int $name * @return void + * @deprecated use ->unset() */ public function __unset(string|int $name): void { - if (isset($_SESSION[$name])) { - unset($_SESSION[$name]); + if (!isset($_SESSION[$name])) { + return; } + $this->restartSession(); + unset($_SESSION[$name]); + $this->closeSessionCall(); } }