Session   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 1
Metric Value
wmc 17
eloc 61
c 7
b 0
f 1
dl 0
loc 184
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A checkSession() 0 6 2
A clear() 0 3 1
A add() 0 7 1
A regenerate() 0 3 1
A set() 0 7 1
A start() 0 51 4
A destroy() 0 16 1
A get() 0 6 1
A has() 0 6 1
A remove() 0 7 1
A setStoragePath() 0 15 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebServCo\Framework\Libraries;
6
7
use WebServCo\Framework\ArrayStorage;
8
use WebServCo\Framework\Exceptions\SessionException;
9
use WebServCo\Framework\Settings;
10
11
final class Session extends \WebServCo\Framework\AbstractLibrary implements
12
    \WebServCo\Framework\Interfaces\SessionInterface
13
{
14
    /**
15
     * @param mixed $setting Can be an array, a string,
16
     *                          or a special formatted string
17
     *                          (eg 'i18n/lang').
18
     * @param mixed $data
19
     */
20
    public function add($setting, $data): bool
21
    {
22
        $this->checkSession();
23
24
25
        $_SESSION = ArrayStorage::add($_SESSION, $setting, $data);
26
        return true;
27
    }
28
29
    /**
30
     * @param mixed $setting Can be an array, a string,
31
     *                          or a special formatted string
32
     *                          (eg 'i18n/lang').
33
     */
34
    public function clear($setting): bool
35
    {
36
        return $this->set($setting, null);
37
    }
38
39
    public function destroy(): bool
40
    {
41
42
        $_SESSION = [];
43
        \WebServCo\Framework\Helpers\CookieLibraryHelper::library()->set(
44
            (string) \session_name(),
45
            '',
46
            \time() - 3600,
47
            $this->setting(\sprintf('cookie%spath', Settings::DIVIDER), '/'),
48
            $this->setting(\sprintf('cookie%sdomain', Settings::DIVIDER), ''),
49
            $this->setting(\sprintf('cookie%ssecure', Settings::DIVIDER), true),
50
            $this->setting(\sprintf('cookie%shttponly', Settings::DIVIDER), true),
51
            $this->setting(\sprintf('cookie%ssamesite', Settings::DIVIDER), 'Lax'),
52
        );
53
        \session_destroy();
54
        return true;
55
    }
56
57
    /**
58
     * @param mixed $setting Can be an array, a string,
59
     *                          or a special formatted string
60
     *                          (eg 'i18n/lang').
61
     * @param mixed $defaultValue
62
     * @return mixed
63
     */
64
    public function get($setting, $defaultValue = null)
65
    {
66
        $this->checkSession();
67
68
69
        return ArrayStorage::get($_SESSION, $setting, $defaultValue);
70
    }
71
72
    /**
73
     * @param mixed $setting Can be an array, a string,
74
     *                          or a special formatted string
75
     *                          (eg 'i18n/lang').
76
     */
77
    public function has($setting): bool
78
    {
79
        $this->checkSession();
80
81
82
        return ArrayStorage::has($_SESSION, $setting);
83
    }
84
85
    public function regenerate(): bool
86
    {
87
        return \session_regenerate_id(true);
88
    }
89
90
    /**
91
     * @param mixed $setting Can be an array, a string,
92
     *                          or a special formatted string
93
     *                          (eg 'i18n/lang').
94
     */
95
    public function remove($setting): bool
96
    {
97
        $this->checkSession();
98
99
100
        $_SESSION = ArrayStorage::remove($_SESSION, $setting);
101
        return true;
102
    }
103
104
    /**
105
     * @param mixed $setting Can be an array, a string,
106
     *                          or a special formatted string
107
     *                          (eg 'i18n/lang').
108
     * @param mixed $value The value to be stored.
109
     */
110
    public function set($setting, $value): bool
111
    {
112
        $this->checkSession();
113
114
115
        $_SESSION = ArrayStorage::set($_SESSION, $setting, $value);
116
        return true;
117
    }
118
119
    public function start(string $storagePath = ''): bool
120
    {
121
        if (\WebServCo\Framework\Helpers\PhpHelper::isCli()) {
122
            throw new SessionException('Not starting session in CLI mode.');
123
        }
124
125
        if (\PHP_SESSION_ACTIVE === \session_status()) {
126
            throw new SessionException('Unable to start session: already started.');
127
        }
128
129
        /**
130
         * Set cache limiter.
131
         */
132
        \session_cache_limiter('public, must-revalidate');
133
134
        /**
135
         * Set cache expire (minutes).
136
         */
137
        \session_cache_expire($this->setting('expire', '36000') / 60);
138
139
        /**
140
         * Set garbage collector timeout (seconds).
141
         */
142
        \ini_set('session.gc_maxlifetime', (string) $this->setting('expire', '36000'));
143
144
        /**
145
        * Set custom session storage path.
146
        */
147
        $this->setStoragePath($storagePath);
148
149
        /**
150
         * Make sure garbage collector visits us.
151
         */
152
        \ini_set('session.gc_probability', '1');
153
154
        \session_set_cookie_params([
155
            'domain' => $this->setting(\sprintf('cookie%sdomain', Settings::DIVIDER), ''),
156
            'httponly' => $this->setting(\sprintf('cookie%shttponly', Settings::DIVIDER), true),
157
            'lifetime' => $this->setting(\sprintf('cookie%slifetime', Settings::DIVIDER), 60 * 60 * 24 * 14),
158
            'path' => $this->setting(\sprintf('cookie%spath', Settings::DIVIDER), '/'),
159
            'samesite' => $this->setting(\sprintf('cookie%ssamesite', Settings::DIVIDER), 'Lax'),
160
            'secure' => $this->setting(\sprintf('cookie%ssecure', Settings::DIVIDER), true),
161
        ]);
162
163
        \session_name('webservco');
164
165
        if (!\session_start()) {
166
            throw new SessionException('Unable to start session.');
167
        }
168
169
        return true;
170
    }
171
172
    protected function checkSession(): bool
173
    {
174
        if (\PHP_SESSION_NONE === \session_status()) {
175
            throw new SessionException('Session is not started.');
176
        }
177
        return true;
178
    }
179
180
    protected function setStoragePath(string $storagePath): bool
181
    {
182
        \ini_set('session.save_path', (string) $storagePath);
183
        $actualStoragePath = \session_save_path($storagePath);
184
185
        if ($actualStoragePath !== $storagePath) {
186
            if ($_SERVER['APP_STRICT_CUSTOM_PATH'] ?? true) { // true unless otherwise specified
187
                throw new SessionException(
188
                    'Unable to set custom session storage path. ' .
189
                    \sprintf('Current path: %s.', $actualStoragePath),
190
                );
191
            }
192
            return false;
193
        }
194
        return true;
195
    }
196
}
197