forked from mongodb/laravel-mongodb
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMongoDbSessionHandler.php
More file actions
117 lines (95 loc) · 2.98 KB
/
MongoDbSessionHandler.php
File metadata and controls
117 lines (95 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace MongoDB\Laravel\Session;
use Illuminate\Session\DatabaseSessionHandler;
use MongoDB\BSON\Binary;
use MongoDB\BSON\Document;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Collection;
use function tap;
use function time;
/**
* Session handler using the MongoDB driver extension.
*/
final class MongoDbSessionHandler extends DatabaseSessionHandler
{
private Collection $collection;
public function close(): bool
{
return true;
}
public function gc($lifetime): int
{
$result = $this->getCollection()->deleteMany(['last_activity' => ['$lt' => $this->getUTCDateTime(-$lifetime)]]);
return $result->getDeletedCount() ?? 0;
}
public function destroy($sessionId): bool
{
$this->getCollection()->deleteOne(['_id' => (string) $sessionId]);
return true;
}
public function read($sessionId): string|false
{
$result = $this->getCollection()->findOne(
['_id' => (string) $sessionId, 'expires_at' => ['$gte' => $this->getUTCDateTime()]],
[
'projection' => ['_id' => false, 'payload' => true],
'typeMap' => ['root' => 'bson'],
],
);
if ($result instanceof Document) {
return (string) $result->payload;
}
return false;
}
public function write($sessionId, $data): bool
{
$payload = $this->getDefaultPayload($data);
$this->getCollection()->replaceOne(
['_id' => (string) $sessionId],
$payload,
['upsert' => true],
);
return true;
}
/** Creates a TTL index that automatically deletes expired objects. */
public function createTTLIndex(): void
{
$this->collection->createIndex(
// UTCDateTime field that holds the expiration date
['expires_at' => 1],
// Delay to remove items after expiration
['expireAfterSeconds' => 0],
);
}
protected function getDefaultPayload($data): array
{
$payload = [
'payload' => new Binary($data),
'last_activity' => $this->getUTCDateTime(),
'expires_at' => $this->getUTCDateTime($this->minutes * 60),
];
if (! $this->container) {
return $payload;
}
return tap($payload, function (&$payload) {
$this->addUserInformation($payload)
->addRequestInformation($payload);
});
}
private function getCollection(): Collection
{
return $this->collection ??= $this->connection->getCollection($this->table);
}
private function getUTCDateTime(int $additionalSeconds = 0): UTCDateTime
{
return new UTCDateTime((time() + $additionalSeconds) * 1000);
}
}