Completed
Branch 2.x (161cec)
by Julián
03:58
created

Filesystem::open()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
/*
4
 * sessionware (https://github.com/juliangut/sessionware).
5
 * PSR7 compatible session management.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/sessionware
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Jgut\Sessionware\Handler;
15
16
use Jgut\Sessionware\Traits\FileHandlerTrait;
17
use Jgut\Sessionware\Traits\HandlerTrait;
18
19
/**
20
 * Filesystem session handler.
21
 */
22
class Filesystem implements Handler
23
{
24
    use HandlerTrait;
25
    use FileHandlerTrait;
26
27
    /**
28
     * @var string
29
     */
30
    protected $savePath;
31
32
    /**
33
     * @var string
34
     */
35
    protected $filePrefix;
36
37
    /**
38
     * File session handler constructor.
39
     *
40
     * @param string $filePrefix
41
     */
42
    public function __construct($filePrefix = 'sess_')
43
    {
44
        $this->filePrefix = $filePrefix;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     *
50
     * @throws \RuntimeException
51
     *
52
     * @SuppressWarnings(PMD.UnusedFormalParameter)
53
     */
54
    public function open($savePath, $sessionName)
55
    {
56
        $this->testConfiguration();
57
58
        $this->savePath = $this->createSavePath($this->configuration->getSavePath(), $this->configuration->getName());
59
60
        return true;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     *
66
     * @return bool
67
     */
68
    public function close()
69
    {
70
        return true;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     *
76
     * @return bool
77
     */
78
    public function destroy($sessionId)
79
    {
80
        $sessionFile = $this->getSessionFile($sessionId);
81
82
        if (file_exists($sessionFile)) {
83
            unlink($sessionFile);
84
        }
85
86
        return false;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function read($sessionId)
93
    {
94
        $sessionFile = $this->getSessionFile($sessionId);
95
96
        if (!file_exists($sessionFile)) {
97
            $sessionData = serialize([]);
98
99
            $this->write($sessionId, $sessionData);
100
101
            return $sessionData;
102
        }
103
104
        $fileDescriptor = fopen($sessionFile, 'rb');
105
        flock($fileDescriptor, \LOCK_SH);
106
107
        $sessionData = stream_get_contents($fileDescriptor);
108
109
        flock($fileDescriptor, \LOCK_UN);
110
        fclose($fileDescriptor);
111
112
        return $this->decryptSessionData($sessionData);
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function write($sessionId, $sessionData)
119
    {
120
        $sessionFile = $this->getSessionFile($sessionId);
121
        if (!file_exists($sessionFile)) {
122
            touch($sessionFile);
123
            chmod($sessionFile, 0777);
124
        }
125
126
        // file_put_contents locking does not support user-land stream wrappers (https://bugs.php.net/bug.php?id=72950)
127
        $fileDescriptor = fopen($sessionFile, 'w');
128
        flock($fileDescriptor, \LOCK_EX);
129
130
        fwrite($fileDescriptor, $this->encryptSessionData($sessionData));
131
132
        flock($fileDescriptor, \LOCK_UN);
133
        fclose($fileDescriptor);
134
135
        return true;
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     *
141
     * @SuppressWarnings(PMD.ShortMethodName)
142
     * @SuppressWarnings(PMD.UnusedFormalParameter)
143
     */
144
    public function gc($maxLifetime)
145
    {
146
        $currentTime = time();
147
148
        foreach (new \DirectoryIterator($this->savePath) as $sessionFile) {
149
            if ($sessionFile->isFile()
150
                && strpos($sessionFile->getFilename(), $this->filePrefix) === 0
151
                && $this->configuration->getLifetime() < ($currentTime - $sessionFile->getMTime())
152
            ) {
153
                unlink($sessionFile->getPathname());
154
            }
155
        }
156
157
        return true;
158
    }
159
160
    /**
161
     * Get session file.
162
     *
163
     * @param string $sessionId
164
     *
165
     * @return string
166
     */
167
    protected function getSessionFile(string $sessionId) : string
168
    {
169
        return $this->savePath . DIRECTORY_SEPARATOR . $this->filePrefix . $sessionId;
170
    }
171
}
172