Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Zur aktuellen Revision | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Session;
4
 
5
use Illuminate\Contracts\Auth\Guard;
6
use Illuminate\Contracts\Container\Container;
7
use Illuminate\Database\ConnectionInterface;
8
use Illuminate\Database\QueryException;
9
use Illuminate\Support\Arr;
10
use Illuminate\Support\Carbon;
11
use Illuminate\Support\InteractsWithTime;
12
use SessionHandlerInterface;
13
 
14
class DatabaseSessionHandler implements ExistenceAwareInterface, SessionHandlerInterface
15
{
16
    use InteractsWithTime;
17
 
18
    /**
19
     * The database connection instance.
20
     *
21
     * @var \Illuminate\Database\ConnectionInterface
22
     */
23
    protected $connection;
24
 
25
    /**
26
     * The name of the session table.
27
     *
28
     * @var string
29
     */
30
    protected $table;
31
 
32
    /**
33
     * The number of minutes the session should be valid.
34
     *
35
     * @var int
36
     */
37
    protected $minutes;
38
 
39
    /**
40
     * The container instance.
41
     *
150 lars 42
     * @var \Illuminate\Contracts\Container\Container|null
148 lars 43
     */
44
    protected $container;
45
 
46
    /**
47
     * The existence state of the session.
48
     *
49
     * @var bool
50
     */
51
    protected $exists;
52
 
53
    /**
54
     * Create a new database session handler instance.
55
     *
56
     * @param  \Illuminate\Database\ConnectionInterface  $connection
57
     * @param  string  $table
58
     * @param  int  $minutes
59
     * @param  \Illuminate\Contracts\Container\Container|null  $container
60
     * @return void
61
     */
62
    public function __construct(ConnectionInterface $connection, $table, $minutes, Container $container = null)
63
    {
64
        $this->table = $table;
65
        $this->minutes = $minutes;
66
        $this->container = $container;
67
        $this->connection = $connection;
68
    }
69
 
70
    /**
71
     * {@inheritdoc}
72
     *
73
     * @return bool
74
     */
75
    public function open($savePath, $sessionName): bool
76
    {
77
        return true;
78
    }
79
 
80
    /**
81
     * {@inheritdoc}
82
     *
83
     * @return bool
84
     */
85
    public function close(): bool
86
    {
87
        return true;
88
    }
89
 
90
    /**
91
     * {@inheritdoc}
92
     *
93
     * @return string|false
94
     */
95
    public function read($sessionId): string|false
96
    {
97
        $session = (object) $this->getQuery()->find($sessionId);
98
 
99
        if ($this->expired($session)) {
100
            $this->exists = true;
101
 
102
            return '';
103
        }
104
 
105
        if (isset($session->payload)) {
106
            $this->exists = true;
107
 
108
            return base64_decode($session->payload);
109
        }
110
 
111
        return '';
112
    }
113
 
114
    /**
115
     * Determine if the session is expired.
116
     *
117
     * @param  \stdClass  $session
118
     * @return bool
119
     */
120
    protected function expired($session)
121
    {
122
        return isset($session->last_activity) &&
123
            $session->last_activity < Carbon::now()->subMinutes($this->minutes)->getTimestamp();
124
    }
125
 
126
    /**
127
     * {@inheritdoc}
128
     *
129
     * @return bool
130
     */
131
    public function write($sessionId, $data): bool
132
    {
133
        $payload = $this->getDefaultPayload($data);
134
 
135
        if (! $this->exists) {
136
            $this->read($sessionId);
137
        }
138
 
139
        if ($this->exists) {
140
            $this->performUpdate($sessionId, $payload);
141
        } else {
142
            $this->performInsert($sessionId, $payload);
143
        }
144
 
145
        return $this->exists = true;
146
    }
147
 
148
    /**
149
     * Perform an insert operation on the session ID.
150
     *
151
     * @param  string  $sessionId
152
     * @param  array<string, mixed>  $payload
153
     * @return bool|null
154
     */
155
    protected function performInsert($sessionId, $payload)
156
    {
157
        try {
158
            return $this->getQuery()->insert(Arr::set($payload, 'id', $sessionId));
159
        } catch (QueryException $e) {
160
            $this->performUpdate($sessionId, $payload);
161
        }
162
    }
163
 
164
    /**
165
     * Perform an update operation on the session ID.
166
     *
167
     * @param  string  $sessionId
168
     * @param  array<string, mixed>  $payload
169
     * @return int
170
     */
171
    protected function performUpdate($sessionId, $payload)
172
    {
173
        return $this->getQuery()->where('id', $sessionId)->update($payload);
174
    }
175
 
176
    /**
177
     * Get the default payload for the session.
178
     *
179
     * @param  string  $data
180
     * @return array
181
     */
182
    protected function getDefaultPayload($data)
183
    {
184
        $payload = [
185
            'payload' => base64_encode($data),
186
            'last_activity' => $this->currentTime(),
187
        ];
188
 
189
        if (! $this->container) {
190
            return $payload;
191
        }
192
 
193
        return tap($payload, function (&$payload) {
194
            $this->addUserInformation($payload)
195
                 ->addRequestInformation($payload);
196
        });
197
    }
198
 
199
    /**
200
     * Add the user information to the session payload.
201
     *
202
     * @param  array  $payload
203
     * @return $this
204
     */
205
    protected function addUserInformation(&$payload)
206
    {
207
        if ($this->container->bound(Guard::class)) {
208
            $payload['user_id'] = $this->userId();
209
        }
210
 
211
        return $this;
212
    }
213
 
214
    /**
215
     * Get the currently authenticated user's ID.
216
     *
217
     * @return mixed
218
     */
219
    protected function userId()
220
    {
221
        return $this->container->make(Guard::class)->id();
222
    }
223
 
224
    /**
225
     * Add the request information to the session payload.
226
     *
227
     * @param  array  $payload
228
     * @return $this
229
     */
230
    protected function addRequestInformation(&$payload)
231
    {
232
        if ($this->container->bound('request')) {
233
            $payload = array_merge($payload, [
234
                'ip_address' => $this->ipAddress(),
235
                'user_agent' => $this->userAgent(),
236
            ]);
237
        }
238
 
239
        return $this;
240
    }
241
 
242
    /**
243
     * Get the IP address for the current request.
244
     *
245
     * @return string
246
     */
247
    protected function ipAddress()
248
    {
249
        return $this->container->make('request')->ip();
250
    }
251
 
252
    /**
253
     * Get the user agent for the current request.
254
     *
255
     * @return string
256
     */
257
    protected function userAgent()
258
    {
259
        return substr((string) $this->container->make('request')->header('User-Agent'), 0, 500);
260
    }
261
 
262
    /**
263
     * {@inheritdoc}
264
     *
265
     * @return bool
266
     */
267
    public function destroy($sessionId): bool
268
    {
269
        $this->getQuery()->where('id', $sessionId)->delete();
270
 
271
        return true;
272
    }
273
 
274
    /**
275
     * {@inheritdoc}
276
     *
277
     * @return int
278
     */
279
    public function gc($lifetime): int
280
    {
281
        return $this->getQuery()->where('last_activity', '<=', $this->currentTime() - $lifetime)->delete();
282
    }
283
 
284
    /**
285
     * Get a fresh query builder instance for the table.
286
     *
287
     * @return \Illuminate\Database\Query\Builder
288
     */
289
    protected function getQuery()
290
    {
291
        return $this->connection->table($this->table);
292
    }
293
 
294
    /**
295
     * Set the application instance used by the handler.
296
     *
297
     * @param  \Illuminate\Contracts\Foundation\Application  $container
298
     * @return $this
299
     */
300
    public function setContainer($container)
301
    {
302
        $this->container = $container;
303
 
304
        return $this;
305
    }
306
 
307
    /**
308
     * Set the existence state for the session.
309
     *
310
     * @param  bool  $value
311
     * @return $this
312
     */
313
    public function setExists($value)
314
    {
315
        $this->exists = $value;
316
 
317
        return $this;
318
    }
319
}