Skip to content

Commit 05d4e68

Browse files
Merge branch '6.4' into 7.0
* 6.4: (28 commits) [Serializer] Fix `@method` annotation fix compatibility with Doctrine DBAL 4 ensure string type with mbstring func overloading enabled [HttpKernel] Fix quotes expectations in tests [Validator] updated Greek translation [Cache][HttpFoundation][Lock] Fix empty username/password for PDO PostgreSQL [HttpClient][WebProfilerBundle] Do not generate cURL command when files are uploaded render newline in front of all script elements fix test fixture fix tests [Cache] Fix property types in PdoAdapter PHP files cannot be executable without shebang [TwigBridge] Mark CodeExtension as @internal Remove full DSNs from exception messages [Yaml] Fix uid binary parsing Disable the "Copy as cURL" button when the debug info are disabled [HttpClient] Replace `escapeshellarg` to prevent overpassing `ARG_MAX` Fix missing `profile` option for console commands [HttpFoundation][Lock] Makes MongoDB adapters usable with `ext-mongodb` only [HttpKernel] Preventing error 500 when function putenv is disabled ...
2 parents 27c5310 + f0179cf commit 05d4e68

File tree

7 files changed

+204
-161
lines changed

7 files changed

+204
-161
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ CHANGELOG
2020
* Add `UriSigner` from the HttpKernel component
2121
* Add `partitioned` flag to `Cookie` (CHIPS Cookie)
2222
* Add argument `bool $flush = true` to `Response::send()`
23+
* Make `MongoDbSessionHandler` instantiable with the mongodb extension directly
2324

2425
6.3
2526
---

HeaderUtils.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public static function parseQuery(string $query, bool $ignoreBrackets = false, s
256256
private static function groupParts(array $matches, string $separators, bool $first = true): array
257257
{
258258
$separator = $separators[0];
259-
$separators = substr($separators, 1);
259+
$separators = substr($separators, 1) ?: '';
260260
$i = 0;
261261

262262
if ('' === $separators && !$first) {

Session/Storage/Handler/MongoDbSessionHandler.php

+59-35
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,22 @@
1414
use MongoDB\BSON\Binary;
1515
use MongoDB\BSON\UTCDateTime;
1616
use MongoDB\Client;
17-
use MongoDB\Collection;
17+
use MongoDB\Driver\BulkWrite;
18+
use MongoDB\Driver\Manager;
19+
use MongoDB\Driver\Query;
1820

1921
/**
20-
* Session handler using the mongodb/mongodb package and MongoDB driver extension.
22+
* Session handler using the MongoDB driver extension.
2123
*
2224
* @author Markus Bachmann <[email protected]>
25+
* @author Jérôme Tamarelle <[email protected]>
2326
*
24-
* @see https://packagist.org/packages/mongodb/mongodb
2527
* @see https://php.net/mongodb
2628
*/
2729
class MongoDbSessionHandler extends AbstractSessionHandler
2830
{
29-
private Client $mongo;
30-
private Collection $collection;
31+
private Manager $manager;
32+
private string $namespace;
3133
private array $options;
3234
private int|\Closure|null $ttl;
3335

@@ -62,13 +64,18 @@ class MongoDbSessionHandler extends AbstractSessionHandler
6264
*
6365
* @throws \InvalidArgumentException When "database" or "collection" not provided
6466
*/
65-
public function __construct(Client $mongo, array $options)
67+
public function __construct(Client|Manager $mongo, array $options)
6668
{
6769
if (!isset($options['database']) || !isset($options['collection'])) {
6870
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.');
6971
}
7072

71-
$this->mongo = $mongo;
73+
if ($mongo instanceof Client) {
74+
$mongo = $mongo->getManager();
75+
}
76+
77+
$this->manager = $mongo;
78+
$this->namespace = $options['database'].'.'.$options['collection'];
7279

7380
$this->options = array_merge([
7481
'id_field' => '_id',
@@ -86,77 +93,94 @@ public function close(): bool
8693

8794
protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
8895
{
89-
$this->getCollection()->deleteOne([
90-
$this->options['id_field'] => $sessionId,
91-
]);
96+
$write = new BulkWrite();
97+
$write->delete(
98+
[$this->options['id_field'] => $sessionId],
99+
['limit' => 1]
100+
);
101+
102+
$this->manager->executeBulkWrite($this->namespace, $write);
92103

93104
return true;
94105
}
95106

96107
public function gc(int $maxlifetime): int|false
97108
{
98-
return $this->getCollection()->deleteMany([
99-
$this->options['expiry_field'] => ['$lt' => new UTCDateTime()],
100-
])->getDeletedCount();
109+
$write = new BulkWrite();
110+
$write->delete(
111+
[$this->options['expiry_field'] => ['$lt' => $this->getUTCDateTime()]],
112+
);
113+
$result = $this->manager->executeBulkWrite($this->namespace, $write);
114+
115+
return $result->getDeletedCount() ?? false;
101116
}
102117

103118
protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
104119
{
105120
$ttl = ($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime');
106-
$expiry = new UTCDateTime((time() + (int) $ttl) * 1000);
121+
$expiry = $this->getUTCDateTime($ttl);
107122

108123
$fields = [
109-
$this->options['time_field'] => new UTCDateTime(),
124+
$this->options['time_field'] => $this->getUTCDateTime(),
110125
$this->options['expiry_field'] => $expiry,
111-
$this->options['data_field'] => new Binary($data, Binary::TYPE_OLD_BINARY),
126+
$this->options['data_field'] => new Binary($data, Binary::TYPE_GENERIC),
112127
];
113128

114-
$this->getCollection()->updateOne(
129+
$write = new BulkWrite();
130+
$write->update(
115131
[$this->options['id_field'] => $sessionId],
116132
['$set' => $fields],
117133
['upsert' => true]
118134
);
119135

136+
$this->manager->executeBulkWrite($this->namespace, $write);
137+
120138
return true;
121139
}
122140

123141
public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
124142
{
125143
$ttl = ($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime');
126-
$expiry = new UTCDateTime((time() + (int) $ttl) * 1000);
144+
$expiry = $this->getUTCDateTime($ttl);
127145

128-
$this->getCollection()->updateOne(
146+
$write = new BulkWrite();
147+
$write->update(
129148
[$this->options['id_field'] => $sessionId],
130149
['$set' => [
131-
$this->options['time_field'] => new UTCDateTime(),
150+
$this->options['time_field'] => $this->getUTCDateTime(),
132151
$this->options['expiry_field'] => $expiry,
133-
]]
152+
]],
153+
['multi' => false],
134154
);
135155

156+
$this->manager->executeBulkWrite($this->namespace, $write);
157+
136158
return true;
137159
}
138160

139161
protected function doRead(#[\SensitiveParameter] string $sessionId): string
140162
{
141-
$dbData = $this->getCollection()->findOne([
163+
$cursor = $this->manager->executeQuery($this->namespace, new Query([
142164
$this->options['id_field'] => $sessionId,
143-
$this->options['expiry_field'] => ['$gte' => new UTCDateTime()],
144-
]);
145-
146-
if (null === $dbData) {
147-
return '';
165+
$this->options['expiry_field'] => ['$gte' => $this->getUTCDateTime()],
166+
], [
167+
'projection' => [
168+
'_id' => false,
169+
$this->options['data_field'] => true,
170+
],
171+
'limit' => 1,
172+
]));
173+
174+
foreach ($cursor as $document) {
175+
return (string) $document->{$this->options['data_field']} ?? '';
148176
}
149177

150-
return $dbData[$this->options['data_field']]->getData();
151-
}
152-
153-
private function getCollection(): Collection
154-
{
155-
return $this->collection ??= $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
178+
// Not found
179+
return '';
156180
}
157181

158-
protected function getMongo(): Client
182+
private function getUTCDateTime(int $additionalSeconds = 0): UTCDateTime
159183
{
160-
return $this->mongo;
184+
return new UTCDateTime((time() + $additionalSeconds) * 1000);
161185
}
162186
}

Session/Storage/Handler/PdoSessionHandler.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ class PdoSessionHandler extends AbstractSessionHandler
9090
/**
9191
* Username when lazy-connect.
9292
*/
93-
private string $username = '';
93+
private ?string $username = null;
9494

9595
/**
9696
* Password when lazy-connect.
9797
*/
98-
private string $password = '';
98+
private ?string $password = null;
9999

100100
/**
101101
* Connection options when lazy-connect.

0 commit comments

Comments
 (0)