1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: *
6: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7: *
8: * For the full copyright and license information, please view
9: * the file license.txt that was distributed with this source code.
10: */
11:
12: namespace Nette\Web;
13:
14: use Nette;
15:
16:
17:
18: /**
19: * Session namespace for Session.
20: *
21: * @author David Grudl
22: */
23: final class SessionNamespace extends Nette\Object implements \IteratorAggregate, \ArrayAccess
24: {
25: /** @var array session data storage */
26: private $data;
27:
28: /** @var array session metadata storage */
29: private $meta;
30:
31: /** @var bool */
32: public $warnOnUndefined = FALSE;
33:
34:
35:
36: /**
37: * Do not call directly. Use Session::getNamespace().
38: */
39: public function __construct(& $data, & $meta)
40: {
41: $this->data = & $data;
42: $this->meta = & $meta;
43: }
44:
45:
46:
47: /**
48: * Returns an iterator over all namespace variables.
49: * @return \ArrayIterator
50: */
51: public function getIterator()
52: {
53: if (isset($this->data)) {
54: return new \ArrayIterator($this->data);
55: } else {
56: return new \ArrayIterator;
57: }
58: }
59:
60:
61:
62: /**
63: * Sets a variable in this session namespace.
64: * @param string name
65: * @param mixed value
66: * @return void
67: */
68: public function __set($name, $value)
69: {
70: $this->data[$name] = $value;
71: if (is_object($value)) {
72: $this->meta[$name]['V'] = Nette\Reflection\ClassReflection::from($value)->getAnnotation('serializationVersion');
73: }
74: }
75:
76:
77:
78: /**
79: * Gets a variable from this session namespace.
80: * @param string name
81: * @return mixed
82: */
83: public function &__get($name)
84: {
85: if ($this->warnOnUndefined && !array_key_exists($name, $this->data)) {
86: trigger_error("The variable '$name' does not exist in session namespace", E_USER_NOTICE);
87: }
88:
89: return $this->data[$name];
90: }
91:
92:
93:
94: /**
95: * Determines whether a variable in this session namespace is set.
96: * @param string name
97: * @return bool
98: */
99: public function __isset($name)
100: {
101: return isset($this->data[$name]);
102: }
103:
104:
105:
106: /**
107: * Unsets a variable in this session namespace.
108: * @param string name
109: * @return void
110: */
111: public function __unset($name)
112: {
113: unset($this->data[$name], $this->meta[$name]);
114: }
115:
116:
117:
118: /**
119: * Sets a variable in this session namespace.
120: * @param string name
121: * @param mixed value
122: * @return void
123: */
124: public function offsetSet($name, $value)
125: {
126: $this->__set($name, $value);
127: }
128:
129:
130:
131: /**
132: * Gets a variable from this session namespace.
133: * @param string name
134: * @return mixed
135: */
136: public function offsetGet($name)
137: {
138: return $this->__get($name);
139: }
140:
141:
142:
143: /**
144: * Determines whether a variable in this session namespace is set.
145: * @param string name
146: * @return bool
147: */
148: public function offsetExists($name)
149: {
150: return $this->__isset($name);
151: }
152:
153:
154:
155: /**
156: * Unsets a variable in this session namespace.
157: * @param string name
158: * @return void
159: */
160: public function offsetUnset($name)
161: {
162: $this->__unset($name);
163: }
164:
165:
166:
167: /**
168: * Sets the expiration of the namespace or specific variables.
169: * @param string|int|DateTime time, value 0 means "until the browser is closed"
170: * @param mixed optional list of variables / single variable to expire
171: * @return SessionNamespace provides a fluent interface
172: */
173: public function setExpiration($time, $variables = NULL)
174: {
175: if (empty($time)) {
176: $time = NULL;
177: $whenBrowserIsClosed = TRUE;
178: } else {
179: $time = Nette\DateTime::from($time)->format('U');
180: $whenBrowserIsClosed = FALSE;
181: }
182:
183: if ($variables === NULL) { // to entire namespace
184: $this->meta['']['T'] = $time;
185: $this->meta['']['B'] = $whenBrowserIsClosed;
186:
187: } elseif (is_array($variables)) { // to variables
188: foreach ($variables as $variable) {
189: $this->meta[$variable]['T'] = $time;
190: $this->meta[$variable]['B'] = $whenBrowserIsClosed;
191: }
192:
193: } else { // to variable
194: $this->meta[$variables]['T'] = $time;
195: $this->meta[$variables]['B'] = $whenBrowserIsClosed;
196: }
197: return $this;
198: }
199:
200:
201:
202: /**
203: * Removes the expiration from the namespace or specific variables.
204: * @param mixed optional list of variables / single variable to expire
205: * @return void
206: */
207: public function removeExpiration($variables = NULL)
208: {
209: if ($variables === NULL) {
210: // from entire namespace
211: unset($this->meta['']['T'], $this->meta['']['B']);
212:
213: } elseif (is_array($variables)) {
214: // from variables
215: foreach ($variables as $variable) {
216: unset($this->meta[$variable]['T'], $this->meta[$variable]['B']);
217: }
218: } else {
219: unset($this->meta[$variables]['T'], $this->meta[$variable]['B']);
220: }
221: }
222:
223:
224:
225: /**
226: * Cancels the current session namespace.
227: * @return void
228: */
229: public function remove()
230: {
231: $this->data = NULL;
232: $this->meta = NULL;
233: }
234:
235: }
236: