GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ApcuHandler   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 67
c 1
b 0
f 0
dl 0
loc 300
rs 9.76
wmc 33

9 Methods

Rating   Name   Duplication   Size   Complexity  
B lockSession() 0 39 8
A close() 0 7 2
A destroy() 0 9 2
A open() 0 11 3
A gc() 0 4 1
A isSupported() 0 3 2
A read() 0 17 3
A lockRelease() 0 16 5
B write() 0 28 7
1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Session\Handlers;
15
16
// ------------------------------------------------------------------------
17
18
use Psr\Log\LoggerInterface;
19
use O2System\Session\Abstracts\AbstractHandler;
20
21
/**
22
 * Class ApcuHandler
23
 *
24
 * @package O2System\Session\Handlers
25
 */
26
class ApcuHandler extends AbstractHandler
27
{
28
    /**
29
     * Platform Name
30
     *
31
     * @access  protected
32
     * @var string
33
     */
34
    protected $platform = 'apcu';
35
36
    // ------------------------------------------------------------------------
37
38
    /**
39
     * ApcHandler::open
40
     *
41
     * Initialize session
42
     *
43
     * @link  http://php.net/manual/en/sessionhandlerinterface.open.php
44
     *
45
     * @param string $save_path The path where to store/retrieve the session.
46
     * @param string $name      The session name.
47
     *
48
     * @return bool <p>
49
     * The return value (usually TRUE on success, FALSE on failure).
50
     * Note this value is returned internally to PHP for processing.
51
     * </p>
52
     * @since 5.4.0
53
     */
54
    public function open($save_path, $name)
55
    {
56
        if ($this->isSupported() === false) {
57
            if ($this->logger instanceof LoggerInterface) {
0 ignored issues
show
introduced by
$this->logger is always a sub-type of Psr\Log\LoggerInterface.
Loading history...
58
                $this->logger->error('SESSION_E_PLATFORM_UNSUPPORTED', ['APC User Cache (APCu)']);
59
            }
60
61
            return $this->failure;
62
        }
63
64
        return $this->success;
65
    }
66
67
    // ------------------------------------------------------------------------
68
69
    /**
70
     * ApcHandler::isSupported
71
     *
72
     * Checks if this platform is supported on this system.
73
     *
74
     * @return bool Returns FALSE if unsupported.
75
     */
76
    public function isSupported()
77
    {
78
        return (bool)(extension_loaded('apcu') && ini_get('apc.enabled'));
79
    }
80
81
    // ------------------------------------------------------------------------
82
83
    /**
84
     * ApcHandler::close
85
     *
86
     * Close the session
87
     *
88
     * @link  http://php.net/manual/en/sessionhandlerinterface.close.php
89
     * @return bool <p>
90
     *        The return value (usually TRUE on success, FALSE on failure).
91
     *        Note this value is returned internally to PHP for processing.
92
     *        </p>
93
     * @since 5.4.0
94
     */
95
    public function close()
96
    {
97
        if (isset($this->lockKey)) {
98
            return apcu_delete($this->lockKey);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_delete($this->lockKey) also could return the type string[] which is incompatible with the documented return type boolean.
Loading history...
99
        }
100
101
        return false;
102
    }
103
104
    // ------------------------------------------------------------------------
105
106
    /**
107
     * ApcHandler::destroy
108
     *
109
     * Destroy a session
110
     *
111
     * @link  http://php.net/manual/en/sessionhandlerinterface.destroy.php
112
     *
113
     * @param string $session_id The session ID being destroyed.
114
     *
115
     * @return bool <p>
116
     * The return value (usually TRUE on success, FALSE on failure).
117
     * Note this value is returned internally to PHP for processing.
118
     * </p>
119
     * @since 5.4.0
120
     */
121
    public function destroy($session_id)
122
    {
123
        if (isset($this->lockKey)) {
124
            apcu_delete($this->prefixKey . $session_id);
125
126
            return $this->destroyCookie();
127
        }
128
129
        return false;
130
    }
131
132
    // ------------------------------------------------------------------------
133
134
    /**
135
     * ApcHandler::gc
136
     *
137
     * Cleanup old sessions
138
     *
139
     * @link  http://php.net/manual/en/sessionhandlerinterface.gc.php
140
     *
141
     * @param int $maxlifetime <p>
142
     *                         Sessions that have not updated for
143
     *                         the last maxlifetime seconds will be removed.
144
     *                         </p>
145
     *
146
     * @return bool <p>
147
     * The return value (usually TRUE on success, FALSE on failure).
148
     * Note this value is returned internally to PHP for processing.
149
     * </p>
150
     * @since 5.4.0
151
     */
152
    public function gc($maxlifetime)
153
    {
154
        // Not necessary, APC takes care of that.
155
        return true;
156
    }
157
158
    // ------------------------------------------------------------------------
159
160
    /**
161
     * ApcHandler::read
162
     *
163
     * Read session data
164
     *
165
     * @link  http://php.net/manual/en/sessionhandlerinterface.read.php
166
     *
167
     * @param string $session_id The session id to read data for.
168
     *
169
     * @return string <p>
170
     * Returns an encoded string of the read data.
171
     * If nothing was read, it must return an empty string.
172
     * Note this value is returned internally to PHP for processing.
173
     * </p>
174
     * @since 5.4.0
175
     */
176
    public function read($session_id)
177
    {
178
        if ($this->lockSession($session_id)) {
179
            // Needed by write() to detect session_regenerate_id() calls
180
            $this->sessionId = $session_id;
181
182
            $success = false;
183
            $sessionData = apcu_fetch($this->prefixKey . $session_id, $success);
184
185
            if ($success) {
186
                $this->fingerprint = md5($sessionData);
0 ignored issues
show
Documentation Bug introduced by
The property $fingerprint was declared of type boolean, but md5($sessionData) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
187
188
                return $sessionData;
189
            }
190
        }
191
192
        return '';
193
    }
194
195
    // ------------------------------------------------------------------------
196
197
    /**
198
     * ApcHandler::_lockSession
199
     *
200
     * Acquires an (emulated) lock.
201
     *
202
     * @param    string $session_id Session ID
203
     *
204
     * @return    bool
205
     */
206
    protected function lockSession($session_id)
207
    {
208
        if (isset($this->lockKey)) {
209
            return apcu_store($this->lockKey, time(), 300);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_store($this->lockKey, time(), 300) also could return the type array which is incompatible with the documented return type boolean.
Loading history...
210
        }
211
212
        // 30 attempts to obtain a lock, in case another request already has it
213
        $lockKey = $this->prefixKey . $session_id . ':lock';
214
        $attempt = 0;
215
216
        do {
217
            if (apcu_exists($lockKey)) {
218
                sleep(1);
219
                continue;
220
            }
221
222
            if ( ! apcu_store($lockKey, time(), 300)) {
223
                if ($this->logger instanceof LoggerInterface) {
224
                    $this->logger->error('SESSION_E_OBTAIN_LOCK', [$this->prefixKey . $session_id]);
225
                }
226
227
                return false;
228
            }
229
230
            $this->lockKey = $lockKey;
231
            break;
232
        } while (++$attempt < 30);
233
234
        if ($attempt === 30) {
235
            if ($this->logger instanceof LoggerInterface) {
0 ignored issues
show
introduced by
$this->logger is always a sub-type of Psr\Log\LoggerInterface.
Loading history...
236
                $this->logger->error('SESSION_E_OBTAIN_LOCK_30', [$this->prefixKey . $session_id]);
237
            }
238
239
            return false;
240
        }
241
242
        $this->isLocked = true;
243
244
        return true;
245
    }
246
247
    //--------------------------------------------------------------------
248
249
    /**
250
     * ApcHandler::write
251
     *
252
     * Write session data
253
     *
254
     * @link  http://php.net/manual/en/sessionhandlerinterface.write.php
255
     *
256
     * @param string $session_id   The session id.
257
     * @param string $sessionData  <p>
258
     *                             The encoded session data. This data is the
259
     *                             result of the PHP internally encoding
260
     *                             the $_SESSION superglobal to a serialized
261
     *                             string and passing it as this parameter.
262
     *                             Please note sessions use an alternative serialization method.
263
     *                             </p>
264
     *
265
     * @return bool <p>
266
     * The return value (usually TRUE on success, FALSE on failure).
267
     * Note this value is returned internally to PHP for processing.
268
     * </p>
269
     * @since 5.4.0
270
     */
271
    public function write($session_id, $sessionData)
272
    {
273
        if ($session_id !== $this->sessionId) {
274
            if ( ! $this->lockRelease() OR ! $this->lockSession($session_id)) {
275
                return false;
276
            }
277
278
            $this->fingerprint = md5('');
0 ignored issues
show
Documentation Bug introduced by
The property $fingerprint was declared of type boolean, but md5('') is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
279
            $this->sessionId = $session_id;
280
        }
281
282
        if (isset($this->lockKey)) {
283
            apcu_store($this->lockKey, time(), 300);
284
285
            if ($this->fingerprint !== ($fingerprint = md5($sessionData))) {
286
                if (apcu_store($this->prefixKey . $session_id, $sessionData, $this->config[ 'lifetime' ])) {
287
                    $this->fingerprint = $fingerprint;
288
289
                    return true;
290
                }
291
292
                return false;
293
            }
294
295
            return apcu_store($this->prefixKey . $session_id, $sessionData, $this->config[ 'lifetime' ]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_store($this-...is->config['lifetime']) also could return the type array which is incompatible with the documented return type boolean.
Loading history...
296
        }
297
298
        return false;
299
    }
300
301
    //--------------------------------------------------------------------
302
303
    /**
304
     * ApcHandler::_lockRelease
305
     *
306
     * Releases a previously acquired lock
307
     *
308
     * @return    bool
309
     */
310
    protected function lockRelease()
311
    {
312
        if (isset($this->lockKey) AND $this->isLocked) {
313
            if ( ! apcu_delete($this->lockKey)) {
314
                if ($this->logger instanceof LoggerInterface) {
0 ignored issues
show
introduced by
$this->logger is always a sub-type of Psr\Log\LoggerInterface.
Loading history...
315
                    $this->logger->error('SESSION_E_FREE_LOCK', [$this->lockKey]);
316
                }
317
318
                return false;
319
            }
320
321
            $this->lockKey = null;
322
            $this->isLocked = false;
323
        }
324
325
        return true;
326
    }
327
}