Passed
Push — master ( 583336...0c4511 )
by smiley
02:30
created

SessionHandlerAbstract::set()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
/**
3
 * Class SessionHandlerAbstract
4
 *
5
 * @filesource   SessionHandlerAbstract.php
6
 * @created      06.03.2017
7
 * @package      chillerlan\Session
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2017 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Session;
14
15
use chillerlan\Logger\LogTrait;
16
use chillerlan\Traits\ContainerInterface;
17
use Psr\Log\LoggerAwareInterface;
18
use SessionHandlerInterface;
19
20
abstract class SessionHandlerAbstract implements SessionHandlerInterface, SessionInterface, LoggerAwareInterface{
21
	use LogTrait;
22
23
	/**
24
	 * @var bool
25
	 */
26
	protected $started = false;
27
28
	/**
29
	 * @var \chillerlan\Session\SessionHandlerOptions
30
	 */
31
	protected $options;
32
33
	/**
34
	 * SessionHandlerAbstract constructor.
35
	 *
36
	 * @param \chillerlan\Traits\ContainerInterface $options
37
	 */
38
	public function __construct(ContainerInterface $options = null){
39
		$this->options = $options ?? new SessionHandlerOptions;
40
		$this->set_session_options();
41
42
		session_set_save_handler($this, true);
43
	}
44
45
	/** @inheritdoc */
46
	public function start():SessionInterface{
47
		$cookie_params = session_get_cookie_params();
48
49
		session_start();
50
		session_regenerate_id(true);
51
52
		setcookie(
53
			session_name(),
54
			session_id(),
55
			time()+$this->options->cookie_lifetime,
56
			$this->options->cookie_path,
57
			$cookie_params['domain']
58
		);
59
60
		return $this;
61
	}
62
63
	/** @inheritdoc */
64
	public function end():SessionInterface{
65
		session_regenerate_id(true);
66
		setcookie(session_name(), '', 0, $this->options->cookie_path);
67
		session_unset();
68
		session_destroy();
69
		session_write_close();
70
71
		return $this;
72
	}
73
74
	/** @inheritdoc */
75
	public function get(string $name){
76
		return $_SESSION[$name] ?? null;
77
	}
78
79
	/** @inheritdoc */
80
	public function set(string $name, $value):SessionInterface{
81
		$_SESSION[$name] = $value;
82
83
		return $this;
84
	}
85
86
	/** @inheritdoc */
87
	public function unset(string $name):SessionInterface{
88
		unset($_SESSION[$name]);
89
90
		return $this;
91
	}
92
93
	/** @inheritdoc */
94
	public function isset(string $name):bool{
95
		return isset($_SESSION[$name]);
96
	}
97
98
	/**
99
	 * @param string $data
100
	 *
101
	 * @return string
102
	 * @throws \chillerlan\Session\SessionHandlerException
103
	 */
104
	protected function encrypt(string &$data):string {
105
106
		if(function_exists('sodium_crypto_secretbox')){
107
			$box = sodium_crypto_secretbox($data, $this::SESSION_NONCE, sodium_hex2bin($this->options->sessionCryptoKey));
108
109
			sodium_memzero($data);
110
111
			return sodium_bin2hex($box);
112
		}
113
114
		throw new SessionHandlerException('sodium not installed'); // @codeCoverageIgnore
115
	}
116
117
	/**
118
	 * @param string $box
119
	 *
120
	 * @return string
121
	 * @throws \chillerlan\Session\SessionHandlerException
122
	 */
123
	protected function decrypt(string $box):string {
124
125
		if(function_exists('sodium_crypto_secretbox_open')){
126
			return sodium_crypto_secretbox_open(sodium_hex2bin($box), $this::SESSION_NONCE, sodium_hex2bin($this->options->sessionCryptoKey));
127
		}
128
129
		throw new SessionHandlerException('sodium not installed'); // @codeCoverageIgnore
130
	}
131
132
	/**
133
	 * @return void
134
	 */
135
	protected function set_session_options(){
136
137
		if(is_writable($this->options->save_path)){
138
			ini_set('session.save_path', $this->options->save_path);
139
		}
140
141
		// @todo http://php.net/manual/session.configuration.php
142
		ini_set('session.name', $this->options->session_name);
143
144
		ini_set('session.gc_maxlifetime', $this->options->gc_maxlifetime);
145
		ini_set('session.gc_probability', 1);
146
		ini_set('session.gc_divisor', 100);
147
148
		ini_set('session.use_strict_mode', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $newvalue of ini_set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

148
		ini_set('session.use_strict_mode', /** @scrutinizer ignore-type */ true);
Loading history...
149
		ini_set('session.use_only_cookies', true);
150
		ini_set('session.cookie_secure', false); // @todo
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $newvalue of ini_set(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
		ini_set('session.cookie_secure', /** @scrutinizer ignore-type */ false); // @todo
Loading history...
151
		ini_set('session.cookie_httponly', true);
152
		ini_set('session.cookie_lifetime', 0);
153
#		ini_set('session.referer_check', '');
154
155
		if(PHP_VERSION_ID < 70100){
156
			ini_set('session.hash_bits_per_character', 6);
157
158
			if(in_array($this->options->hash_algo, hash_algos())){
159
				ini_set('session.hash_function', $this->options->hash_algo);
160
			}
161
		}
162
		else{
163
			ini_set('session.sid_bits_per_character', 6);
164
			ini_set('session.sid_length', 128);
165
		}
166
167
	}
168
169
}
170