Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
87.69% |
57 / 65 |
|
87.50% |
14 / 16 |
CRAP | |
0.00% |
0 / 1 |
SessionNamespace | |
87.69% |
57 / 65 |
|
87.50% |
14 / 16 |
35.03 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
setNamespace | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getNamespace | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setTimedValue | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
setRequestValue | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
init | |
57.14% |
8 / 14 |
|
0.00% |
0 / 1 |
5.26 | |||
kill | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
5.39 | |||
checkRequest | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
checkRequests | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
checkExpiration | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
checkExpirations | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
toArray | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
__set | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__get | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
__isset | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__unset | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Session; |
15 | |
16 | /** |
17 | * Session namespace class |
18 | * |
19 | * @category Pop |
20 | * @package Pop\Session |
21 | * @author Nick Sagona, III <dev@nolainteractive.com> |
22 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
23 | * @license http://www.popphp.org/license New BSD License |
24 | * @version 4.0.0 |
25 | */ |
26 | class SessionNamespace extends AbstractSession |
27 | { |
28 | |
29 | /** |
30 | * Session namespace |
31 | * @var ?string |
32 | */ |
33 | private ?string $namespace = null; |
34 | |
35 | /** |
36 | * Constructor |
37 | * |
38 | * Private method to instantiate the session object |
39 | * |
40 | * @param string $namespace |
41 | * @throws Exception |
42 | */ |
43 | public function __construct(string $namespace) |
44 | { |
45 | if ($namespace == '_POP_SESSION_') { |
46 | throw new Exception("Error: Cannot use the reserved namespace '_POP_SESSION_'."); |
47 | } |
48 | $this->setNamespace($namespace); |
49 | $sess = Session::getInstance(); |
50 | if (!isset($sess[$namespace])) { |
51 | $sess[$namespace] = []; |
52 | } |
53 | $this->init(); |
54 | } |
55 | |
56 | /** |
57 | * Set current namespace |
58 | * |
59 | * @param string $namespace |
60 | * @return SessionNamespace |
61 | */ |
62 | public function setNamespace(string $namespace): SessionNamespace |
63 | { |
64 | $this->namespace = $namespace; |
65 | return $this; |
66 | } |
67 | |
68 | /** |
69 | * Get current namespace |
70 | * |
71 | * @return string |
72 | */ |
73 | public function getNamespace(): string |
74 | { |
75 | return $this->namespace; |
76 | } |
77 | |
78 | /** |
79 | * Set a time-based value |
80 | * |
81 | * @param string $key |
82 | * @param mixed $value |
83 | * @param int $expire |
84 | * @return SessionNamespace |
85 | */ |
86 | public function setTimedValue(string $key, mixed $value, int $expire = 300): SessionNamespace |
87 | { |
88 | $_SESSION[$this->namespace][$key] = $value; |
89 | $_SESSION['_POP_SESSION_'][$this->namespace]['expirations'][$key] = time() + (int)$expire; |
90 | return $this; |
91 | } |
92 | |
93 | /** |
94 | * Set a request-based value |
95 | * |
96 | * @param string $key |
97 | * @param mixed $value |
98 | * @param int $hops |
99 | * @return SessionNamespace |
100 | */ |
101 | public function setRequestValue(string $key, mixed $value, int $hops = 1): SessionNamespace |
102 | { |
103 | $_SESSION[$this->namespace][$key] = $value; |
104 | $_SESSION['_POP_SESSION_'][$this->namespace]['requests'][$key] = [ |
105 | 'current' => 0, |
106 | 'limit' => (int)$hops |
107 | ]; |
108 | return $this; |
109 | } |
110 | |
111 | /** |
112 | * Init the session |
113 | * |
114 | * @return void |
115 | */ |
116 | private function init(): void |
117 | { |
118 | if (!isset($_SESSION['_POP_SESSION_'])) { |
119 | $_SESSION['_POP_SESSION_'] = [ |
120 | $this->namespace => [ |
121 | 'requests' => [], |
122 | 'expirations' => [] |
123 | ] |
124 | ]; |
125 | } else if (isset($_SESSION['_POP_SESSION_']) && !isset($_SESSION['_POP_SESSION_'][$this->namespace])) { |
126 | $_SESSION['_POP_SESSION_'][$this->namespace] = [ |
127 | 'requests' => [], |
128 | 'expirations' => [] |
129 | ]; |
130 | } else { |
131 | $this->checkRequests(); |
132 | $this->checkExpirations(); |
133 | } |
134 | } |
135 | |
136 | /** |
137 | * Kill the session namespace |
138 | * |
139 | * @param bool $all |
140 | * @return void |
141 | */ |
142 | public function kill(bool $all = false): void |
143 | { |
144 | if ($all) { |
145 | $sess = Session::getInstance(); |
146 | $sess->kill(); |
147 | } else if (isset($_SESSION[$this->namespace])) { |
148 | if (isset($_SESSION['_POP_SESSION_'][$this->namespace])) { |
149 | unset($_SESSION['_POP_SESSION_'][$this->namespace]); |
150 | } |
151 | if (isset($_SESSION[$this->namespace])) { |
152 | unset($_SESSION[$this->namespace]); |
153 | } |
154 | } |
155 | } |
156 | |
157 | /** |
158 | * Check the request-based session value |
159 | * |
160 | * @return void |
161 | */ |
162 | private function checkRequest($key): void |
163 | { |
164 | if (isset($_SESSION['_POP_SESSION_'][$this->namespace]['requests'][$key])) { |
165 | $_SESSION['_POP_SESSION_'][$this->namespace]['requests'][$key]['current']++; |
166 | $current = $_SESSION['_POP_SESSION_'][$this->namespace]['requests'][$key]['current']; |
167 | $limit = $_SESSION['_POP_SESSION_'][$this->namespace]['requests'][$key]['limit']; |
168 | if ($current > $limit) { |
169 | unset($_SESSION[$this->namespace][$key]); |
170 | unset($_SESSION['_POP_SESSION_'][$this->namespace]['requests'][$key]); |
171 | } |
172 | } |
173 | } |
174 | |
175 | /** |
176 | * Check the request-based session values |
177 | * |
178 | * @return void |
179 | */ |
180 | private function checkRequests(): void |
181 | { |
182 | foreach ($_SESSION[$this->namespace] as $key => $value) { |
183 | $this->checkRequest($key); |
184 | } |
185 | } |
186 | |
187 | /** |
188 | * Check the time-based session value |
189 | * |
190 | * @return void |
191 | */ |
192 | private function checkExpiration($key): void |
193 | { |
194 | if (isset($_SESSION['_POP_SESSION_'][$this->namespace]['expirations'][$key]) && |
195 | (time() > $_SESSION['_POP_SESSION_'][$this->namespace]['expirations'][$key])) { |
196 | unset($_SESSION[$this->namespace][$key]); |
197 | unset($_SESSION['_POP_SESSION_'][$this->namespace]['expirations'][$key]); |
198 | } |
199 | } |
200 | |
201 | /** |
202 | * Check the time-based session values |
203 | * |
204 | * @return void |
205 | */ |
206 | private function checkExpirations(): void |
207 | { |
208 | foreach ($_SESSION[$this->namespace] as $key => $value) { |
209 | $this->checkExpiration($key); |
210 | } |
211 | } |
212 | |
213 | /** |
214 | * Get the session values as an array |
215 | * |
216 | * @return array |
217 | */ |
218 | public function toArray(): array |
219 | { |
220 | $session = $_SESSION; |
221 | |
222 | if (isset($session['_POP_SESSION_'])) { |
223 | unset($session['_POP_SESSION_']); |
224 | } |
225 | |
226 | return $session[$this->namespace] ?? []; |
227 | } |
228 | |
229 | /** |
230 | * Set a property in the session object that is linked to the $_SESSION global variable |
231 | * |
232 | * @param string $name |
233 | * @param mixed $value |
234 | * @return void |
235 | */ |
236 | public function __set(string $name, mixed $value): void |
237 | { |
238 | $_SESSION[$this->namespace][$name] = $value; |
239 | } |
240 | |
241 | /** |
242 | * Get method to return the value of the $_SESSION global variable |
243 | * |
244 | * @param string $name |
245 | * @return mixed |
246 | */ |
247 | public function __get(string $name): mixed |
248 | { |
249 | return (isset($_SESSION[$this->namespace][$name])) ? $_SESSION[$this->namespace][$name] : null; |
250 | } |
251 | |
252 | /** |
253 | * Return the isset value of the $_SESSION global variable |
254 | * |
255 | * @param string $name |
256 | * @return bool |
257 | */ |
258 | public function __isset(string $name): bool |
259 | { |
260 | return isset($_SESSION[$this->namespace][$name]); |
261 | } |
262 | |
263 | /** |
264 | * Unset the $_SESSION global variable |
265 | * |
266 | * @param string $name |
267 | * @return void |
268 | */ |
269 | public function __unset(string $name): void |
270 | { |
271 | $_SESSION[$this->namespace][$name] = null; |
272 | unset($_SESSION[$this->namespace][$name]); |
273 | } |
274 | |
275 | } |