1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
namespace Zewa\HTTP; |
4
|
|
|
|
5
|
|
|
use Zewa\Container; |
6
|
|
|
use Zewa\Security; |
7
|
|
|
|
8
|
|
|
final class Session extends SuperGlobal |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* @var array |
12
|
|
|
*/ |
13
|
|
|
private $flashdata = []; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @var string index for flash data |
17
|
|
|
*/ |
18
|
|
|
public $flashdataId = '__flash_data'; |
19
|
|
|
|
20
|
21 |
|
public function __construct(Container $container, Security $security) |
21
|
|
|
{ |
22
|
21 |
|
parent::__construct($container, $security); |
23
|
|
|
|
24
|
21 |
|
$this->flashManagement(); |
25
|
21 |
|
$session = $_SESSION ?? []; |
26
|
21 |
|
$this->registerGlobal($session); |
27
|
21 |
|
} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Processes current requests flashdata, recycles old. |
31
|
|
|
* @access private |
32
|
|
|
*/ |
33
|
21 |
|
private function flashManagement() |
34
|
|
|
{ |
35
|
21 |
|
$flashdata = $_SESSION[$this->flashdataId] ?? null; |
36
|
|
|
|
37
|
21 |
|
if ($flashdata !== null) { |
38
|
5 |
|
$flashdata = unserialize(base64_decode($flashdata)); |
39
|
5 |
|
unset($_SESSION[$this->flashdataId]); |
40
|
5 |
|
if (!empty($flashdata)) { |
41
|
5 |
|
$this->flashdata = $flashdata; |
42
|
5 |
|
$this->incrementFlashStorage(); |
43
|
|
|
} |
44
|
|
|
} |
45
|
21 |
|
} |
46
|
|
|
|
47
|
5 |
|
private function incrementFlashStorage() |
48
|
|
|
{ |
49
|
|
|
// var_dump($this->flashdata); |
|
|
|
|
50
|
5 |
|
foreach ($this->flashdata as $variable => $data) { |
51
|
5 |
|
if ($this->flashdata[$variable]['increment'] > 1) { |
52
|
2 |
|
unset($_SESSION[$variable], $this->flashdata[$variable]); |
53
|
|
|
} else { |
54
|
3 |
|
$this->flashdata[$variable]['value'] = $data['value']; |
55
|
5 |
|
$this->flashdata[$variable]['increment'] ++; |
56
|
|
|
} |
57
|
|
|
} |
58
|
|
|
|
59
|
5 |
|
if (!empty($this->flashdata)) { |
60
|
3 |
|
$_SESSION[$this->flashdataId] = base64_encode(serialize($this->flashdata)); |
61
|
|
|
} |
62
|
5 |
|
} |
63
|
|
|
|
64
|
|
|
// Because sessions persist, we need to do a little more work here.. |
65
|
|
|
// In addition, most superglobals are immuteable, whereas session is not |
66
|
2 |
|
public function set(string $key, $value) |
67
|
|
|
{ |
68
|
2 |
|
$key = $this->security->normalize($key); |
69
|
2 |
|
$value = $this->security->normalize($value); |
70
|
2 |
|
parent::set($key, $value); // TODO: Change the autogenerated stub |
71
|
2 |
|
$_SESSION[$key] = $value; |
72
|
2 |
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @param $name |
76
|
|
|
* @param $value |
77
|
|
|
*/ |
78
|
1 |
|
public function setFlash($name, $value) |
79
|
|
|
{ |
80
|
1 |
|
$current = $this->flashdata ?? []; |
81
|
1 |
|
$current[$name] = ['value' => $value, 'increment' => 0]; |
82
|
1 |
|
$flash = $this->security->normalize($current); |
83
|
1 |
|
$_SESSION[$this->flashdataId] = base64_encode(serialize($flash)); |
84
|
1 |
|
$this->flashdata = $flash; |
85
|
1 |
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @param string $key |
89
|
|
|
* @param null $default |
90
|
|
|
* @return array|null |
91
|
|
|
*/ |
92
|
2 |
|
public function getFlash(string $key, $default = null) |
93
|
|
|
{ |
94
|
|
|
// print_r($this->flashdata); |
|
|
|
|
95
|
|
|
|
96
|
2 |
|
return $this->flashdata[$key]['value'] ?? $default; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* destroys a session and related cookies |
101
|
|
|
*/ |
102
|
1 |
|
public function destroy() |
103
|
|
|
{ |
104
|
1 |
|
$_SESSION = []; |
105
|
|
|
|
106
|
1 |
|
if (ini_get("session.use_cookies")) { |
107
|
1 |
|
$params = session_get_cookie_params(); |
108
|
1 |
|
$time = time() - 42000; |
109
|
1 |
|
$path = $params['path']; |
110
|
1 |
|
$domain = $params['domain']; |
111
|
1 |
|
$secure = $params['secure']; |
112
|
1 |
|
$http = $params['httponly']; |
113
|
1 |
|
setcookie(session_name(), '', $time, $path, $domain, $secure, $http); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
|
117
|
1 |
|
$this->container->remove('Session'); |
118
|
|
|
|
119
|
1 |
|
session_destroy(); |
120
|
1 |
|
} |
121
|
|
|
} |
122
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.