Passed
Push — develop ( 1af474...95fb2f )
by nguereza
02:14
created

Session::init()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 26
rs 9.7
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * Platine Session
5
 *
6
 * Platine Session is the lightweight implementation of php native
7
 * session handler interface
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Session
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file Session.php
34
 *
35
 *  The Session class used to manage the session
36
 *
37
 *  @package    Platine\Session
38
 *  @author Platine Developers Team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   https://www.platine-php.com
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Session;
49
50
use Platine\Session\Configuration;
51
use Platine\Session\Storage\NullStorage;
52
use Platine\Stdlib\Helper\Arr;
53
use SessionHandlerInterface;
54
55
class Session
56
{
57
    /**
58
     * The session driver to use
59
     * @var SessionHandlerInterface
60
     */
61
    protected SessionHandlerInterface $handler;
62
63
    /**
64
     * The configuration instance
65
     * @var Configuration
66
     */
67
    protected Configuration $config;
68
69
    /**
70
     * Create new Session instance
71
     * @param SessionHandlerInterface|null $handler the handler to use
72
     * @param Configuration|null $config the configuration to use
73
     */
74
    public function __construct(
75
        ?SessionHandlerInterface $handler = null,
76
        ?Configuration $config = null
77
    ) {
78
        $this->config = $config ?? new Configuration([]);
79
80
        $this->handler = $handler ?? new NullStorage($config);
81
82
        if ((session_status() !== PHP_SESSION_ACTIVE)) {
83
            $this->init();
84
            session_set_save_handler($this->handler, true);
85
86
            //now start the session
87
            session_start();
88
        }
89
    }
90
91
    /**
92
     * Return the instance of session handler
93
     * @return SessionHandlerInterface
94
     */
95
    public function getHandler(): SessionHandlerInterface
96
    {
97
        return $this->handler;
98
    }
99
100
    /**
101
     * Check whether the session data for given key exists
102
     * @param  string  $key
103
     * @return boolean
104
     */
105
    public function has(string $key): bool
106
    {
107
        return Arr::has($_SESSION, $key);
108
    }
109
110
    /**
111
     * Set the session data
112
     * @param string $key   the key name
113
     * @param mixed $value the session data value
114
     */
115
    public function set(string $key, $value): void
116
    {
117
        Arr::set($_SESSION, $key, $value);
118
    }
119
120
    /**
121
     * Get the session data
122
     * @param string $key   the key name
123
     * @param mixed $default the default value to return if can
124
     *  not find session data
125
     * @return mixed
126
     */
127
    public function get(string $key, $default = null)
128
    {
129
        return Arr::get($_SESSION, $key, $default);
130
    }
131
132
    /**
133
     * Return all session data
134
     * @param  bool $includeFlash whether to include flash data
135
     * @return array<string, mixed>
136
     */
137
    public function all(bool $includeFlash = false): array
138
    {
139
        $session = $_SESSION;
140
        $flashKey = $this->config->get('flash_key');
141
        if (!$includeFlash) {
142
            if (array_key_exists($flashKey, $session)) {
143
                unset($session[$flashKey]);
144
            }
145
        }
146
147
        return $session;
148
    }
149
150
    /**
151
     * Remove the session data for the given key
152
     * @param string $key   the key name
153
     *
154
     * @return bool
155
     */
156
    public function remove(string $key): bool
157
    {
158
        Arr::forget($_SESSION, $key);
159
160
        return true;
161
    }
162
163
    /**
164
     * Check whether the session flash data for given key exists
165
     * @param  string  $key
166
     * @return boolean
167
     */
168
    public function hasFlash(string $key): bool
169
    {
170
        $flashKey = $this->config->get('flash_key');
171
        $name = sprintf('%s.%s', $flashKey, $key);
172
173
        return $this->has($name);
174
    }
175
176
    /**
177
     * Get the session flash data
178
     * @param string $key   the key name
179
     * @param mixed $default the default value to return if can
180
     *  not find session data
181
     * @return mixed
182
     */
183
    public function getFlash(string $key, $default = null)
184
    {
185
        $flashKey = $this->config->get('flash_key');
186
        $name = sprintf('%s.%s', $flashKey, $key);
187
188
        $value = $default;
189
        if ($this->has($name)) {
190
            $value = $this->get($name);
191
            $this->removeFlash($key);
192
        }
193
194
        return $value;
195
    }
196
197
    /**
198
     * Set the session flash data
199
     * @param string $key   the key name
200
     * @param mixed $value the session data value
201
     */
202
    public function setFlash(string $key, $value): void
203
    {
204
        $flashKey = $this->config->get('flash_key');
205
        $name = sprintf('%s.%s', $flashKey, $key);
206
207
        $this->set($name, $value);
208
    }
209
210
    /**
211
     * Remove the session data for the given key
212
     * @param string $key   the key name
213
     *
214
     * @return bool
215
     */
216
    public function removeFlash(string $key): bool
217
    {
218
        $flashKey = $this->config->get('flash_key');
219
        $name = sprintf('%s.%s', $flashKey, $key);
220
        $this->remove($name);
221
222
        return true;
223
    }
224
225
    /**
226
     * Set the session information
227
     * @return void
228
     */
229
    protected function init(): void
230
    {
231
        $sessionName = $this->config->get('name');
232
        if ($sessionName) {
233
            session_name($sessionName);
234
        }
235
236
        $lifetime = (int)$this->config->get('cookie.lifetime');
237
        $path = $this->config->get('cookie.path');
238
        $domain = $this->config->get('cookie.domain');
239
        $secure = $this->config->get('cookie.secure');
240
241
        session_set_cookie_params([
242
            'lifetime' => $lifetime,
243
            'path' => $path,
244
            'domain' => $domain,
245
            'secure' => $secure,
246
            'httponly' => true, // for security for access to cookie via javascript or XSS attack
247
            'samesite' => 'Lax'
248
        ]);
249
250
        //to prevent attack of Session Fixation
251
        //thank to https://www.phparch.com/2018/01/php-sessions-in-depth/
252
        ini_set('session.use_strict_mode', '1');
253
        ini_set('session.use_only_cookies', '1');
254
        ini_set('session.use_trans_sid', '0');
255
    }
256
}
257