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