diff --git a/system/Session/Session.php b/system/Session/Session.php index 0540c1508a9e..9cf65f3cde25 100644 --- a/system/Session/Session.php +++ b/system/Session/Session.php @@ -817,39 +817,31 @@ public function removeTempdata(string $key) */ public function markAsTempdata($key, int $ttl = 300): bool { - $ttl += Time::now()->getTimestamp(); + $time = Time::now()->getTimestamp(); + $keys = is_array($key) ? $key : [$key]; - if (is_array($key)) { - $temp = []; - - foreach ($key as $k => $v) { - // Do we have a key => ttl pair, or just a key? - if (is_int($k)) { - $k = $v; - $v = $ttl; - } elseif (is_string($v)) { - $v = Time::now()->getTimestamp() + $ttl; - } else { - $v += Time::now()->getTimestamp(); - } + if (array_is_list($keys)) { + $keys = array_fill_keys($keys, $ttl); + } - if (! array_key_exists($k, $_SESSION)) { - return false; - } + $tempdata = []; - $temp[$k] = $v; + foreach ($keys as $sessionKey => $timeToLive) { + if (! array_key_exists($sessionKey, $_SESSION)) { + return false; } - $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars']) ? array_merge($_SESSION['__ci_vars'], $temp) : $temp; - - return true; - } + if (is_int($timeToLive)) { + $timeToLive += $time; + } else { + $timeToLive = $time + $ttl; + } - if (! isset($_SESSION[$key])) { - return false; + $tempdata[$sessionKey] = $timeToLive; } - $_SESSION['__ci_vars'][$key] = $ttl; + $_SESSION['__ci_vars'] ??= []; + $_SESSION['__ci_vars'] = [...$_SESSION['__ci_vars'], ...$tempdata]; return true; } diff --git a/tests/system/Session/SessionTest.php b/tests/system/Session/SessionTest.php index 7a8de643cc35..d469c595cd4f 100644 --- a/tests/system/Session/SessionTest.php +++ b/tests/system/Session/SessionTest.php @@ -476,6 +476,23 @@ public function testSetTempDataArraySingleTTL(): void $this->assertLessThanOrEqual($_SESSION['__ci_vars']['baz'], $time + 200); } + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/9534 + */ + public function testSetTempDataOnArrayData(): void + { + $session = $this->getInstance(); + $session->start(); + + $time = time(); + + $session->setTempdata(['foo1' => 'bar1'], null, 200); + $session->setTempdata('foo2', 'bar2', 200); + + $this->assertLessThanOrEqual($_SESSION['__ci_vars']['foo1'], $time + 200); + $this->assertLessThanOrEqual($_SESSION['__ci_vars']['foo2'], $time + 200); + } + /** * @see https://github.com/codeigniter4/CodeIgniter4/pull/9536#discussion_r2051798869 */ diff --git a/user_guide_src/source/changelogs/v4.6.1.rst b/user_guide_src/source/changelogs/v4.6.1.rst index 2eb8db9600f3..8a327aea5f9e 100644 --- a/user_guide_src/source/changelogs/v4.6.1.rst +++ b/user_guide_src/source/changelogs/v4.6.1.rst @@ -40,6 +40,7 @@ Bugs Fixed - **Database:** Fixed a bug in ``Postgre`` and ``SQLite3`` handlers where composite unique keys were not fully taken into account for ``upsert`` type of queries. - **Database:** Fixed a bug in the ``OCI8`` and ``SQLSRV`` drivers where ``getVersion()`` returned an empty string when the database connection was not yet established. - **Logger:** Fixed a bug where the ``{line}`` variable couldn't be used without specifying the ``{file}`` variable when logging the message. +- **Session:** Fixed a bug where ``Session::markAsTempdata()`` would give the wrong TTL when array data is supplied to ``Session::setTempdata()``. - **Toolbar:** Fixed a bug where setting ``maxHistory`` to ``0`` would produce a JavaScript error in the Debug Toolbar. - **Toolbar:** Fixed a bug where setting ``maxHistory`` to ``0`` prevented log files from being properly cleared.