1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-06 22:57:14 +02:00

Issue #5482 Session handling of array data.

This commit is contained in:
camer0n
2025-04-28 08:59:28 -07:00
parent 8b5a83e4bf
commit 46696f2124
3 changed files with 132 additions and 78 deletions

View File

@@ -640,6 +640,8 @@ class theme_admin_ui extends e_admin_ui
public function InfoPage() public function InfoPage()
{ {
if(!empty($_GET['src'])) // online mode. if(!empty($_GET['src'])) // online mode.
{ {
$string = base64_decode($_GET['src']); $string = base64_decode($_GET['src']);
@@ -657,7 +659,7 @@ class theme_admin_ui extends e_admin_ui
$tm = (string) $this->getId(); $tm = (string) $this->getId();
$themeMeta = e107::getTheme($tm)->get(); $themeMeta = e107::getTheme($tm)->get();
echo $this->themeObj->renderThemeInfo($themeMeta); return $this->themeObj->renderThemeInfo($themeMeta);
} }
@@ -1176,6 +1178,9 @@ class theme_admin_form_ui extends e_admin_form_ui
e107::getSession()->set('thememanager/online/'.$theme['id'], $theme); e107::getSession()->set('thememanager/online/'.$theme['id'], $theme);
$saved = e107::getSession()->get('thememanager/online/'.$theme['id']);
$d = http_build_query($srcData,false); $d = http_build_query($srcData,false);
$base64 = base64_encode($d); $base64 = base64_encode($d);
@@ -1388,7 +1393,7 @@ class theme_builder extends e_admin_ui
$newThemeXML = e_THEME.$this->themeName."/theme.xml"; $newThemeXML = e_THEME.$this->themeName."/theme.xml";
if(file_exists($newThemeXML)) if(file_exists($newThemeXML))
{ {
$info = e107::getTheme()->getThemeInfo($this->themeName); $info = e107::getTheme()::getThemeInfo($this->themeName);
e107::getDebug()->log($info); e107::getDebug()->log($info);

View File

@@ -260,21 +260,58 @@ class e_session
/** /**
* Retrieve value from current session namespace * Retrieve value from current session namespace
* Equals to $_SESSION[NAMESPACE][$key] * Equals to $_SESSION[NAMESPACE][$key] or a multi-dimensional array for keys starting with $key/
* @param string $key * @param string $key
* @param bool $clear unset key * @param bool $clear unset key
* @return mixed * @return mixed
*/ */
public function get($key, $clear = false) public function get($key, $clear = false)
{ {
$ret = $this->_data[$key] ?? null; $result = [];
if($clear) $this->clear($key);
// Check for keys starting with $key/
foreach ($this->_data as $dataKey => $value) {
if (strpos($dataKey, $key . '/') === 0) {
$subKeys = explode('/', substr($dataKey, strlen($key . '/')));
$current = &$result;
foreach ($subKeys as $k) {
if (!isset($current[$k])) {
$current[$k] = [];
}
$current = &$current[$k];
}
$current = $value;
}
}
// Merge with direct key value if it exists
if (isset($this->_data[$key])) {
if (is_array($this->_data[$key]) && is_array($result)) {
$result = array_merge_recursive($this->_data[$key], $result);
} else {
$result = $this->_data[$key];
}
}
// Return null if no data found
$ret = empty($result) && !isset($this->_data[$key]) ? null : $result;
if ($clear) {
$this->clear($key);
// Clear all related keys
foreach (array_keys($this->_data) as $dataKey) {
if (strpos($dataKey, $key . '/') === 0) {
unset($this->_data[$dataKey]);
}
}
}
return $ret; return $ret;
} }
/** /**
* Retrieve value from current session namespace * Retrieve value from current session namespace
* If key is null, returns all current session namespace data * If key is null, returns all current session namespace data as a multi-dimensional array
* *
* @param string|null $key * @param string|null $key
* @param bool $clear * @param bool $clear
@@ -282,51 +319,64 @@ class e_session
*/ */
public function getData($key = null, $clear = false) public function getData($key = null, $clear = false)
{ {
if(null === $key) if (null === $key) {
{ $result = [];
$ret = $this->_data; foreach ($this->_data as $dataKey => $value) {
if($clear) $this->clearData(); $keys = explode('/', $dataKey);
return $ret; $current = &$result;
foreach ($keys as $k) {
if (!isset($current[$k])) {
$current[$k] = [];
}
$current = &$current[$k];
}
$current = $value;
}
if ($clear) {
$this->clearData();
}
return $result;
} }
return $this->get($key, $clear); return $this->get($key, $clear);
} }
/**
* Flatten a nested array into path-based keys.
*
* @param array $array The nested array to flatten
* @param string $prefix The prefix for the current key path
* @return array Flat array of key-value pairs
*/
private function flattenArray($array, $prefix = '')
{
$result = [];
foreach ($array as $key => $value) {
$newKey = $prefix ? $prefix . '/' . $key : $key;
if (is_array($value)) {
$result = array_merge($result, $this->flattenArray($value, $newKey));
} else {
$result[$newKey] = $value;
}
}
return $result;
}
/** /**
* Set value in current session namespace * Set value in current session namespace
* Equals to $_SESSION[NAMESPACE][$key] = $value * Equals to $_SESSION[NAMESPACE][$key] = $value
* @param string $key Also accepts multi-dimensional format. key1/key2 * @param string $key Also accepts path-based format (e.g., key1/key2)
* @param mixed $value * @param mixed $value Any value type (string, array, integer, etc.)
* @return e_session * @return e_session
*/ */
public function set($key, $value) public function set($key, $value)
{ {
if(strpos($key,'/') !== false) // multi-dimensional $this->_data[$key] = $value;
{
$keyArr = explode('/',$key);
$count = count($keyArr);
if($count === 2)
{
list($k1, $k2) = $keyArr;
$this->_data[$k1][$k2] = $value;
}
elseif($count === 3)
{
list($k1, $k2, $k3) = $keyArr;
$this->_data[$k1][$k2][$k3] = $value;
}
}
else
{
$this->_data[$key] = $value;
}
return $this; return $this;
} }
/** /**
* Set value in current session namespace * Set value in current session namespace
* If $key is array, the whole namespace array will be replaced with it, * If $key is array, the whole namespace array will be replaced with it (flattened),
* $value will be ignored * $value will be ignored
* @param string|array|null $key * @param string|array|null $key
* @param mixed $value * @param mixed $value
@@ -334,9 +384,8 @@ class e_session
*/ */
public function setData($key, $value = null) public function setData($key, $value = null)
{ {
if(is_array($key)) if (is_array($key)) {
{ $this->_data = $this->flattenArray($key);
$this->_data = $key;
return $this; return $this;
} }
return $this->set($key, $value); return $this->set($key, $value);
@@ -382,33 +431,12 @@ class e_session
*/ */
public function clear($key = null) public function clear($key = null)
{ {
if($key === null) // clear all under this namespace. if ($key === null) {
{ $this->_data = array();
$this->_data = array(); // must be set to array() not unset.
return $this; return $this;
} }
if(strpos($key,'/') !== false) // multi-dimensional unset($this->_data[$key]);
{
$keyArr = explode('/',$key);
$count = count($keyArr);
if($count === 2)
{
list($k1, $k2) = $keyArr;
unset($this->_data[$k1][$k2]);
}
elseif($count === 3)
{
list($k1, $k2, $k3) = $keyArr;
unset($this->_data[$k1][$k2][$k3]);
}
}
else
{
unset($this->_data[$key]);
}
return $this; return $this;
} }
@@ -953,17 +981,17 @@ class e_core_session extends e_session
$details = "HOST: ".$_SERVER['HTTP_HOST']."\n"; $details = "HOST: ".$_SERVER['HTTP_HOST']."\n";
$details .= "REQUEST_URI: ".$_SERVER['REQUEST_URI']."\n"; $details .= "REQUEST_URI: ".$_SERVER['REQUEST_URI']."\n";
$details .= ($_POST['e-token']) ? "e-token (POST): ".$_POST['e-token']."\n" : ""; $details .= ($_POST['e-token']) ? "e-token (POST): ".$_POST['e-token']."\n" : "";
$details .= ($_GET['e-token']) ? "e-token (GET): ".$_GET['e-token']."\n" : ""; $details .= ($_GET['e-token']) ? "e-token (GET): ".$_GET['e-token']."\n" : "";
$details .= ($_POST['e_token']) ? "AJAX e_token (POST): ".$_POST['e_token']."\n" : ""; $details .= ($_POST['e_token']) ? "AJAX e_token (POST): ".$_POST['e_token']."\n" : "";
/* /*
$utoken = $this->getFormToken(false); $utoken = $this->getFormToken(false);
$details .= "raw token: ".$utoken."\n"; $details .= "raw token: ".$utoken."\n";
$details .= "checkFormToken (e-token should match this): ".md5($utoken)."\n"; $details .= "checkFormToken (e-token should match this): ".md5($utoken)."\n";
$details .= "md5(e-token): ".md5($_POST['e-token'])."\n";*/ $details .= "md5(e-token): ".md5($_POST['e-token'])."\n";*/
/* /*
$regenerate = $this->get('__form_token_regenerate'); $regenerate = $this->get('__form_token_regenerate');
$details .= "Regenerate after: ".date('r', $regenerate)." (".$regenerate.")\n"; $details .= "Regenerate after: ".date('r', $regenerate)." (".$regenerate.")\n";
*/ */
$details .= "has __form_token: "; $details .= "has __form_token: ";
@@ -1275,10 +1303,10 @@ class e_session_db implements SessionHandlerInterface
* @param int $max_lifetime * @param int $max_lifetime
* @return bool * @return bool
*/ */
public function gc(int $max_lifetime): int|false public function gc(int $max_lifetime): int|false
{ {
return $this->_db->delete($this->getTable(), '`session_expires`<'.time()); return $this->_db->delete($this->getTable(), '`session_expires`<'.time());
} }
/** /**
* Allow only well formed session id string * Allow only well formed session id string

View File

@@ -63,7 +63,7 @@
); );
$result = $this->sess->get('clear'); $result = $this->sess->get('clear');
$this->assertSame($expected, $result); $this::assertSame($expected, $result);
} }
@@ -77,7 +77,7 @@
$result = $this->sess->get('whatever'); $result = $this->sess->get('whatever');
$this->assertEquals($expected, $result); $this::assertEquals($expected, $result);
// Multi-dimensional array support. // Multi-dimensional array support.
@@ -92,9 +92,30 @@
); );
$result = $newsess->get('customer'); $result = $newsess->get('customer');
$this->assertSame($expected, $result); $this::assertSame($expected, $result);
} }
function testSetGetArrayDepth()
{
// Flat
$array = ['a', 'b', 'c'];
e107::getSession()->set('thememanager', $array);
$result = e107::getSession()->get('thememanager');
$this::assertSame($array, $result);
// 1-level deep
$array2 = ['d', 'e', 'f'];
e107::getSession()->set('thememanager/online', $array2);
$result = e107::getSession()->get('thememanager/online');
$this::assertSame($array2, $result);
// 2-levels deep
$array3 = ['g', 'h', 'i'];
e107::getSession()->set('thememanager/online/55', $array3);
$result = e107::getSession()->get('thememanager/online/55');
$this::assertSame($array3, $result);
}
/* /*
public function testGetOption() public function testGetOption()
{ {