diff --git a/library/Icinga/Web/Session/PhpSession.php b/library/Icinga/Web/Session/PhpSession.php index 86d66b244..5df9e8744 100644 --- a/library/Icinga/Web/Session/PhpSession.php +++ b/library/Icinga/Web/Session/PhpSession.php @@ -138,6 +138,7 @@ class PhpSession extends Session */ public function read() { + $this->clear(); $this->open(); foreach ($_SESSION as $key => $value) { @@ -161,9 +162,15 @@ class PhpSession extends Session { $this->open(); + foreach ($this->removed as $key) { + unset($_SESSION[$key]); + } foreach ($this->values as $key => $value) { $_SESSION[$key] = $value; } + foreach ($this->removedNamespaces as $identifier) { + unset($_SESSION[self::NAMESPACE_PREFIX . $identifier]); + } foreach ($this->namespaces as $identifier => $namespace) { $_SESSION[self::NAMESPACE_PREFIX . $identifier] = $namespace->getAll(); } diff --git a/library/Icinga/Web/Session/Session.php b/library/Icinga/Web/Session/Session.php index 0717601ed..e81274e73 100644 --- a/library/Icinga/Web/Session/Session.php +++ b/library/Icinga/Web/Session/Session.php @@ -41,6 +41,13 @@ abstract class Session extends SessionNamespace */ protected $namespaces = array(); + /** + * The identifiers of all namespaces removed from this session + * + * @var array + */ + protected $removedNamespaces = array(); + /** * Read all values from the underlying session implementation */ @@ -71,6 +78,10 @@ abstract class Session extends SessionNamespace public function getNamespace($identifier) { if (!isset($this->namespaces[$identifier])) { + if (in_array($identifier, $this->removedNamespaces)) { + unset($this->removedNamespaces[array_search($identifier, $this->removedNamespaces)]); + } + $this->namespaces[$identifier] = new SessionNamespace(); } @@ -97,6 +108,7 @@ abstract class Session extends SessionNamespace public function removeNamespace($identifier) { unset($this->namespaces[$identifier]); + $this->removedNamespaces[] = $identifier; } /** @@ -105,6 +117,8 @@ abstract class Session extends SessionNamespace public function clear() { $this->values = array(); + $this->removed = array(); $this->namespaces = array(); + $this->removedNamespaces = array(); } } diff --git a/library/Icinga/Web/Session/SessionNamespace.php b/library/Icinga/Web/Session/SessionNamespace.php index 9c49c3f63..4360e2828 100644 --- a/library/Icinga/Web/Session/SessionNamespace.php +++ b/library/Icinga/Web/Session/SessionNamespace.php @@ -45,6 +45,13 @@ class SessionNamespace implements IteratorAggregate */ protected $values = array(); + /** + * The names of all values removed from this container + * + * @var array + */ + protected $removed = array(); + /** * Return an iterator for all values in this namespace * @@ -52,7 +59,7 @@ class SessionNamespace implements IteratorAggregate */ public function getIterator() { - return new ArrayIterator($this->values); + return new ArrayIterator($this->getAll()); } /** @@ -77,7 +84,7 @@ class SessionNamespace implements IteratorAggregate public function __get($key) { if (!array_key_exists($key, $this->values)) { - throw new Exception('Cannot access non-existent session value "' + $key + '"'); + throw new Exception('Cannot access non-existent session value "' . $key . '"'); } return $this->get($key); @@ -101,6 +108,7 @@ class SessionNamespace implements IteratorAggregate */ public function __unset($key) { + $this->removed[] = $key; unset($this->values[$key]); } @@ -115,6 +123,11 @@ class SessionNamespace implements IteratorAggregate public function set($key, $value) { $this->values[$key] = $value; + + if (in_array($key, $this->removed)) { + unset($this->removed[array_search($key, $this->values)]); + } + return $this; } @@ -150,10 +163,10 @@ class SessionNamespace implements IteratorAggregate public function setAll(array $values, $overwrite = false) { foreach ($values as $key => $value) { - if (isset($this->values[$key]) && !$overwrite) { + if ($this->get($key) !== $value && !$overwrite) { continue; } - $this->values[$key] = $value; + $this->set($key, $value); } } }