diff --git a/src/Request.php b/src/Request.php index acc3e94..b2c895f 100644 --- a/src/Request.php +++ b/src/Request.php @@ -64,12 +64,13 @@ public static function getMethod() * - cookie $_COOKIE * - env $_ENV * - server $_SERVER + * - session $_SESSION (returns default if no active session) * - method via current $_SERVER['REQUEST_METHOD'] * - default $_REQUEST * * @param string $name Variable name * @param mixed $default Default value if the variable does not exist - * @param string $hash Source of variable value (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Source of variable value (GET, POST, FILES, COOKIE, ENV, SERVER, SESSION, METHOD, DEFAULT/REQUEST) * @param string $type Return type for the variable (INT, FLOAT, BOOLEAN, WORD, * ALPHANUM, CMD, BASE64, STRING, ARRAY, PATH, NONE) For more * information see FilterInput::clean(). @@ -106,6 +107,13 @@ public static function getVar($name, $default = null, $hash = 'default', $type = case 'SERVER': $input = &$_SERVER; break; + case 'SESSION': + if (session_status() !== PHP_SESSION_ACTIVE) { + $input = []; + break; + } + $input = &$_SESSION; + break; default: $input = &$_REQUEST; break; @@ -114,13 +122,11 @@ public static function getVar($name, $default = null, $hash = 'default', $type = if (isset($input[$name]) && null !== $input[$name]) { // Get the variable from the input hash and clean it $var = static::cleanVar($input[$name], $mask, $type); - } elseif (null !== $default) { // Clean the default value $var = static::cleanVar($default, $mask, $type); } else { $var = $default; - } return $var; @@ -135,7 +141,7 @@ public static function getVar($name, $default = null, $hash = 'default', $type = * * @param string $name Variable name * @param int $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return int Requested variable */ @@ -153,7 +159,7 @@ public static function getInt($name, $default = 0, $hash = 'default') * * @param string $name Variable name * @param float $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return float Requested variable */ @@ -171,7 +177,7 @@ public static function getFloat($name, $default = 0.0, $hash = 'default') * * @param string $name Variable name * @param bool $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return bool Requested variable */ @@ -189,7 +195,7 @@ public static function getBool($name, $default = false, $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string Requested variable */ @@ -206,7 +212,7 @@ public static function getWord($name, $default = '', $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string Requested variable */ @@ -224,7 +230,7 @@ public static function getCmd($name, $default = '', $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * @param int $mask Filter mask for the variable * * @return string Requested variable @@ -240,7 +246,7 @@ public static function getString($name, $default = '', $hash = 'default', $mask * * @param string $name Variable name * @param mixed $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return array */ @@ -254,7 +260,7 @@ public static function getArray($name, $default = array(), $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string Requested variable */ @@ -268,7 +274,7 @@ public static function getText($name, $default = '', $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string Requested variable */ @@ -282,7 +288,7 @@ public static function getUrl($name, $default = '', $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string Requested variable */ @@ -296,7 +302,7 @@ public static function getPath($name, $default = '', $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string email address or default if invalid */ @@ -311,7 +317,7 @@ public static function getEmail($name, $default = '', $hash = 'default') * * @param string $name Variable name * @param string $default Default value if the variable does not exist - * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, METHOD) + * @param string $hash Where the var should come from (POST, GET, FILES, COOKIE, ENV, SERVER, SESSION, METHOD) * * @return string IP address or default if invalid */ @@ -385,9 +391,11 @@ public static function hasVar($name, $hash = 'default') /** * Set a variable in one of the request variables * + * For SESSION, the write is silently skipped if no session is active. + * * @param string $name Name * @param string $value Value - * @param string $hash Hash + * @param string $hash Hash (GET, POST, REQUEST, COOKIE, FILES, ENV, SERVER, SESSION, METHOD) * @param bool $overwrite Boolean * * @return string Previous value @@ -437,6 +445,11 @@ public static function setVar($name, $value = null, $hash = 'method', $overwrite case 'SERVER': $_SERVER[$name] = $value; break; + case 'SESSION': + if (session_status() === PHP_SESSION_ACTIVE) { + $_SESSION[$name] = $value; + } + break; } return $previous; @@ -457,10 +470,11 @@ public static function setVar($name, $value = null, $hash = 'method', $overwrite * - cookie $_COOKIE * - env $_ENV * - server $_SERVER + * - session $_SESSION (returns empty if no active session) * - method via current $_SERVER['REQUEST_METHOD'] * - default $_REQUEST * - * @param string $hash to get (POST, GET, FILES, METHOD) + * @param string $hash to get (GET, POST, FILES, COOKIE, ENV, SERVER, SESSION, METHOD, DEFAULT/REQUEST) * @param int $mask Filter mask for the variable * * @return mixed Request hash @@ -492,6 +506,13 @@ public static function get($hash = 'default', $mask = 0) case 'SERVER': $input = &$_SERVER; break; + case 'SESSION': + if (session_status() !== PHP_SESSION_ACTIVE) { + $input = []; + break; + } + $input = &$_SESSION; + break; default: $input = $_REQUEST; break; @@ -506,7 +527,7 @@ public static function get($hash = 'default', $mask = 0) * Sets a request variable * * @param array $array An associative array of key-value pairs - * @param string $hash The request variable to set (POST, GET, FILES, METHOD) + * @param string $hash The request variable to set (GET, POST, REQUEST, COOKIE, FILES, ENV, SERVER, SESSION, METHOD) * @param bool $overwrite If true and an existing key is found, the value is overwritten, * otherwise it is ignored * diff --git a/tests/unit/RequestTest.php b/tests/unit/RequestTest.php index 05bfcbc..ee3fcf1 100644 --- a/tests/unit/RequestTest.php +++ b/tests/unit/RequestTest.php @@ -10,6 +10,11 @@ class RequestTest extends \PHPUnit\Framework\TestCase */ protected $object; + /** + * @var array Original session INI values saved by startTestSession() + */ + private array $savedSessionIni = []; + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -25,6 +30,15 @@ protected function setUp(): void */ protected function tearDown(): void { + // Ensure full cleanup even if a test fails mid-way + if (session_status() === PHP_SESSION_ACTIVE) { + $_SESSION = []; + session_destroy(); + } + foreach ($this->savedSessionIni as $key => $value) { + ini_set($key, $value); + } + $this->savedSessionIni = []; } public function testGetMethod() @@ -257,4 +271,172 @@ public function testSet() $this->assertEquals($_REQUEST[$varname], 'Pourquoi'); } + /** + * Attempt to start a session for testing. + * + * Disables cookie-based session IDs (not available in CLI), starts the + * session, and verifies it became active. Skips the calling test if + * sessions cannot be started in this environment. + */ + private function startTestSession(): void + { + if (session_status() === PHP_SESSION_ACTIVE) { + $_SESSION = []; + return; + } + $iniKeys = ['session.use_cookies', 'session.use_only_cookies', 'session.cache_limiter']; + foreach ($iniKeys as $key) { + if (!isset($this->savedSessionIni[$key])) { + $this->savedSessionIni[$key] = (string) ini_get($key); + } + } + ini_set('session.use_cookies', '0'); + ini_set('session.use_only_cookies', '0'); + ini_set('session.cache_limiter', ''); + $started = @session_start(); + if ($started === false || session_status() !== PHP_SESSION_ACTIVE) { + $this->markTestSkipped('Cannot start a session in this environment.'); + } + $_SESSION = []; + } + + /** + * Close any active session and verify it is no longer active. + */ + private function closeTestSession(): void + { + if (session_status() === PHP_SESSION_ACTIVE) { + $_SESSION = []; + session_destroy(); + } + $this->assertNotSame( + PHP_SESSION_ACTIVE, + session_status(), + 'Session should not be active after close.' + ); + } + + public function testGetVarSessionWithActiveSession() + { + $this->startTestSession(); + $varname = 'RequestTestSession'; + $_SESSION[$varname] = 'session_value'; + + try { + $this->assertEquals('session_value', Request::getVar($varname, null, 'session')); + } finally { + unset($_SESSION[$varname]); + $this->closeTestSession(); + } + } + + public function testGetVarSessionReturnsDefaultWhenKeyMissing() + { + $this->startTestSession(); + + try { + $this->assertNull(Request::getVar('no_such_session_key', null, 'session')); + $this->assertEquals('fallback', Request::getVar('no_such_session_key', 'fallback', 'session')); + } finally { + $this->closeTestSession(); + } + } + + public function testGetVarSessionReturnsDefaultWhenNoSession() + { + $this->startTestSession(); + $this->closeTestSession(); + + $this->assertNull(Request::getVar('any_key', null, 'session')); + $this->assertEquals('default_val', Request::getVar('any_key', 'default_val', 'session')); + } + + public function testGetIntFromSession() + { + $this->startTestSession(); + $varname = 'RequestTestSessionInt'; + $_SESSION[$varname] = '42'; + + try { + $this->assertEquals(42, Request::getInt($varname, 0, 'session')); + } finally { + unset($_SESSION[$varname]); + $this->closeTestSession(); + } + } + + public function testGetSessionHash() + { + $this->startTestSession(); + $varname = 'RequestTestSessionGet'; + $_SESSION[$varname] = 'get_session_value'; + + try { + $get = Request::get('session'); + $this->assertTrue(is_array($get)); + $this->assertEquals('get_session_value', $get[$varname]); + } finally { + unset($_SESSION[$varname]); + $this->closeTestSession(); + } + } + + public function testGetSessionHashReturnsEmptyWhenNoSession() + { + $this->startTestSession(); + $this->closeTestSession(); + + $get = Request::get('session'); + $this->assertTrue(is_array($get)); + $this->assertEmpty($get); + } + + public function testSetVarSession() + { + $this->startTestSession(); + $varname = 'XMF_TEST_SESSION_VAR'; + $value = 'session_set_value'; + + try { + Request::setVar($varname, $value, 'session'); + $this->assertArrayHasKey($varname, $_SESSION); + $this->assertEquals($value, $_SESSION[$varname]); + } finally { + unset($_SESSION[$varname]); + $this->closeTestSession(); + } + } + + public function testSetVarSessionIgnoredWhenNoSession() + { + $this->startTestSession(); + $this->closeTestSession(); + + $varname = 'XMF_TEST_SESSION_NO_WRITE'; + Request::setVar($varname, 'should_not_persist', 'session'); + + // Re-open session and verify the write was skipped + $this->startTestSession(); + try { + $this->assertArrayNotHasKey($varname, $_SESSION); + } finally { + $this->closeTestSession(); + } + } + + public function testHasVarSession() + { + $this->startTestSession(); + $varname = 'RequestTestHasVarSession'; + + try { + $this->assertFalse(Request::hasVar($varname, 'session')); + $_SESSION[$varname] = 'exists'; + $this->assertTrue(Request::hasVar($varname, 'session')); + } finally { + unset($_SESSION[$varname]); + $this->closeTestSession(); + } + } + }