Passed
Push — master ( 48e2e4...58f05f )
by Marwan
08:52
created

Session.php$0 ➔ message()   A

Complexity

Conditions 2

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 17
ccs 9
cts 9
cp 1
crap 2
rs 9.7
1
<?php
2
3
/**
4
 * @author Marwan Al-Soltany <[email protected]>
5
 * @copyright Marwan Al-Soltany 2021
6
 * For the full copyright and license information, please view
7
 * the LICENSE file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace MAKS\Velox\Backend;
13
14
use MAKS\Velox\Backend\Session\Flash;
15
use MAKS\Velox\Backend\Session\CSRF;
16
use MAKS\Velox\Backend\Config;
17
18
/**
19
 * A class that offers a simple interface to work with sessions.
20
 *
21
 * Example:
22
 * ```
23
 * // start a session
24
 * Session::start();
25
 *
26
 * // check for variable availability
27
 * $someVarExists = Session::has('someVar');
28
 *
29
 * // set a session variable
30
 * Session::set('someVar', $value);
31
 *
32
 * // get a session variable
33
 * $someVar = Session::get('someVar');
34
 *
35
 * // destroy a session
36
 * Session::destroy();
37
 *
38
 * // get an instance of the Flash class
39
 * $flash = Session::flash();
40
 *
41
 * // get an instance of the CSRF class
42
 * $flash = Session::csrf();
43
 * ```
44
 *
45
 * @package Velox\Backend
46
 * @since 1.3.0
47
 * @api
48
 */
49
final class Session
50
{
51
    /**
52
     * Class constructor.
53
     *
54
     * @param int|null $expiration Session expiration time in minutes.
55
     * @param string|null $limiter Session limiter.
56
     * @param string|null $path Session save path.
57
     */
58 26
    public function __construct(?int $expiration = null, ?string $limiter = null, ?string $path = null)
59
    {
60 26
        $this->start($expiration, $limiter, $path);
61 26
    }
62
63
    /**
64
     * Starts the session if it is not already started.
65
     *
66
     * @param int|null [optional] $expiration Session expiration time in minutes.
67
     * @param string|null [optional] $limiter Session limiter.
68
     * @param string|null [optional] $path Session save path.
69
     *
70
     * @return bool True if the session was started, false otherwise.
71
     */
72 31
    public static function start(?int $expiration = null, ?string $limiter = null, ?string $path = null): bool
73
    {
74 31
        $path       ??= Config::get('session.path', Config::get('global.paths.storage') . '/sessions');
75 31
        $limiter    ??= Config::get('session.cache.limiter', 'nocache');
76 31
        $expiration ??= Config::get('session.cache.expiration', 180);
77
78 31
        file_exists($path) || mkdir($path, 0744, true);
79
80 31
        session_save_path() != $path && session_save_path($path);
81 31
        session_cache_expire() != $expiration && session_cache_expire($expiration);
82 31
        session_cache_limiter() != $limiter && session_cache_limiter($limiter);
83
84 31
        $status = session_status() != PHP_SESSION_NONE || session_start(['name' => 'VELOX']);
85
86 31
        return $status;
87
    }
88
89
    /**
90
     * Destroys all of the data associated with the current session.
91
     * This method does not unset any of the global variables associated with the session, or unset the session cookie.
92
     *
93
     * @return bool True if the session was destroyed, false otherwise.
94
     */
95 1
    public static function destroy(): bool
96
    {
97 1
        return session_destroy();
98
    }
99
100
    /**
101
     * Unsets the session superglobal
102
     * This method deletes (truncates) only the variables in the session, session still exists.
103
     *
104
     * @return bool True if the session was unset, false otherwise.
105
     */
106 1
    public static function unset(): bool
107
    {
108 1
        return session_unset();
109
    }
110
111
    /**
112
     * Clears the session entirely.
113
     * This method will unset the session, destroy the session, commit (close writing) to the session, and reset the session cookie (new expiration).
114
     *
115
     * @return bool True if the session was cleared, false otherwise.
116
     */
117 1
    public static function clear(): bool
118
    {
119 1
        $name   = session_name();
120 1
        $cookie = session_get_cookie_params();
121
122 1
        setcookie($name, '', 0, $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httponly'] ?? false);
123
        // not testable in CLI, headers already sent
124
        // @codeCoverageIgnoreStart
125
        $unset   = session_unset();
126
        $destroy = session_destroy();
127
        $commit  = session_commit();
128
129
        return ($unset && $destroy && $commit);
130
        // @codeCoverageIgnoreEnd
131
    }
132
133
    /**
134
     * Checks if a value exists in the session.
135
     *
136
     * @param string $key The key to check. Dot-notation can be used with nested arrays.
137
     *
138
     * @return bool True if the key exists, false otherwise.
139
     */
140 12
    public static function has(string $key): bool
141
    {
142 12
        return Globals::getSession($key) !== null;
143
    }
144
145
    /**
146
     * Gets a value from the session.
147
     *
148
     * @param string $key The key to get. Dot-notation can be used with nested arrays.
149
     *
150
     * @return mixed The value of the key, or null if the key does not exist.
151
     */
152 15
    public static function get(string $key)
153
    {
154 15
        return Globals::getSession($key);
155
    }
156
157
    /**
158
     * Sets a value in the session.
159
     *
160
     * @param string $key The key to set. Dot-notation can be used with nested arrays.
161
     * @param mixed $value The value to set.
162
     *
163
     * @return static The current instance.
164
     */
165 7
    public static function set(string $key, $value)
166
    {
167 7
        Globals::setSession($key, $value);
168
169 7
        return new static();
170
    }
171
172
    /**
173
     * Cuts a value from the session. The value will be returned and the key will be unset from the array.
174
     *
175
     * @param string $key The key to cut. Dot-notation can be used with nested arrays.
176
     *
177
     * @return mixed The value of the key, or null if the key does not exist.
178
     */
179 12
    public static function cut(string $key)
180
    {
181 12
        return Globals::cutSession($key);
182
    }
183
184
185
    /**
186
     * Writes a flash message to the session.
187
     * This method can be invoked without arguments, in that case a `Flash` object will be returned.
188
     *
189
     * @param string $type [optional] Message type.
190
     * @param string $text [optional] Message text.
191
     * @param bool $now [optional] Whether to write and make the message available for rendering immediately or wait for the next request.
192
     *
193
     * @return Flash
194
     */
195 1
    public static function flash(string $text = '', string $type = '', bool $now = false): Flash
196
    {
197 1
        static $flash = null;
198
199 1
        if ($flash === null) {
200 1
            $flash = new Flash();
201
        }
202
203 1
        if (strlen(trim($text))) {
204 1
            $flash($type, $text, $now);
205
        }
206
207 1
        return $flash;
208
    }
209
210
    /**
211
     * Returns an instance of the CSRF class.
212
     *
213
     * @param string $name [optional] The name of the CSRF token. Default to `{session.csrf.name}` configuration value.
214
     * If a token name other than the default is specified, validation of this token has to be implemented manually.
215
     *
216
     * @return CSRF
217
     */
218 5
    public static function csrf(?string $name = null): CSRF
219
    {
220 5
        return new CSRF($name);
221
    }
222
}
223