1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Http;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22:
23: final class SessionSection extends Nette\Object implements \IteratorAggregate, \ArrayAccess
24: {
25:
26: private $session;
27:
28:
29: private $name;
30:
31:
32: private $data;
33:
34:
35: private $meta = FALSE;
36:
37:
38: public $warnOnUndefined = FALSE;
39:
40:
41:
42: 43: 44:
45: public function __construct(Session $session, $name)
46: {
47: if (!is_string($name)) {
48: throw new Nette\InvalidArgumentException("Session namespace must be a string, " . gettype($name) ." given.");
49: }
50:
51: $this->session = $session;
52: $this->name = $name;
53: }
54:
55:
56:
57: 58: 59:
60: private function start()
61: {
62: if ($this->meta === FALSE) {
63: $this->session->start();
64: $this->data = & $_SESSION['__NF']['DATA'][$this->name];
65: $this->meta = & $_SESSION['__NF']['META'][$this->name];
66: }
67: }
68:
69:
70:
71: 72: 73: 74:
75: public function getIterator()
76: {
77: $this->start();
78: if (isset($this->data)) {
79: return new \ArrayIterator($this->data);
80: } else {
81: return new \ArrayIterator;
82: }
83: }
84:
85:
86:
87: 88: 89: 90: 91: 92:
93: public function __set($name, $value)
94: {
95: $this->start();
96: $this->data[$name] = $value;
97: if (is_object($value)) {
98: $this->meta[$name]['V'] = Nette\Reflection\ClassType::from($value)->getAnnotation('serializationVersion');
99: }
100: }
101:
102:
103:
104: 105: 106: 107: 108:
109: public function &__get($name)
110: {
111: $this->start();
112: if ($this->warnOnUndefined && !array_key_exists($name, $this->data)) {
113: trigger_error("The variable '$name' does not exist in session section", E_USER_NOTICE);
114: }
115:
116: return $this->data[$name];
117: }
118:
119:
120:
121: 122: 123: 124: 125:
126: public function __isset($name)
127: {
128: if ($this->session->exists()) {
129: $this->start();
130: }
131: return isset($this->data[$name]);
132: }
133:
134:
135:
136: 137: 138: 139: 140:
141: public function __unset($name)
142: {
143: $this->start();
144: unset($this->data[$name], $this->meta[$name]);
145: }
146:
147:
148:
149: 150: 151: 152: 153: 154:
155: public function offsetSet($name, $value)
156: {
157: $this->__set($name, $value);
158: }
159:
160:
161:
162: 163: 164: 165: 166:
167: public function offsetGet($name)
168: {
169: return $this->__get($name);
170: }
171:
172:
173:
174: 175: 176: 177: 178:
179: public function offsetExists($name)
180: {
181: return $this->__isset($name);
182: }
183:
184:
185:
186: 187: 188: 189: 190:
191: public function offsetUnset($name)
192: {
193: $this->__unset($name);
194: }
195:
196:
197:
198: 199: 200: 201: 202: 203:
204: public function setExpiration($time, $variables = NULL)
205: {
206: $this->start();
207: if (empty($time)) {
208: $time = NULL;
209: $whenBrowserIsClosed = TRUE;
210: } else {
211: $time = Nette\DateTime::from($time)->format('U');
212: $max = ini_get('session.gc_maxlifetime');
213: if ($time - time() > $max + 3) {
214: trigger_error("The expiration time is greater than the session expiration $max seconds", E_USER_NOTICE);
215: }
216: $whenBrowserIsClosed = FALSE;
217: }
218:
219: if ($variables === NULL) {
220: $this->meta['']['T'] = $time;
221: $this->meta['']['B'] = $whenBrowserIsClosed;
222:
223: } elseif (is_array($variables)) {
224: foreach ($variables as $variable) {
225: $this->meta[$variable]['T'] = $time;
226: $this->meta[$variable]['B'] = $whenBrowserIsClosed;
227: }
228:
229: } else {
230: $this->meta[$variables]['T'] = $time;
231: $this->meta[$variables]['B'] = $whenBrowserIsClosed;
232: }
233: return $this;
234: }
235:
236:
237:
238: 239: 240: 241: 242:
243: public function removeExpiration($variables = NULL)
244: {
245: $this->start();
246: if ($variables === NULL) {
247:
248: unset($this->meta['']['T'], $this->meta['']['B']);
249:
250: } elseif (is_array($variables)) {
251:
252: foreach ($variables as $variable) {
253: unset($this->meta[$variable]['T'], $this->meta[$variable]['B']);
254: }
255: } else {
256: unset($this->meta[$variables]['T'], $this->meta[$variable]['B']);
257: }
258: }
259:
260:
261:
262: 263: 264: 265:
266: public function remove()
267: {
268: $this->start();
269: $this->data = NULL;
270: $this->meta = NULL;
271: }
272:
273: }
274: