Passed
Push — master ( bf0683...f36612 )
by Radu
02:26
created

Session::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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