Skip to content

Commit 1ef9c7f

Browse files
committed
Use separate compatibility classes for Symfony 6 on PHP 8+
1 parent 4a1920e commit 1ef9c7f

4 files changed

Lines changed: 175 additions & 8 deletions

File tree

src/Ratchet/Session/Storage/Proxy/VirtualProxy.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
namespace Ratchet\Session\Storage\Proxy;
33
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
44

5+
if (PHP_VERSION_ID > 80000 && (new \ReflectionMethod('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy','getId'))->hasReturnType()) {
6+
// alias to class for Symfony 6 on PHP 8+ that uses native types like `getId(): string`
7+
class_alias(__NAMESPACE__ . '\\VirtualProxyForSymfony6', __NAMESPACE__ . '\\VirtualProxy');
8+
} else {
9+
// fall back to class without native types
10+
511
class VirtualProxy extends SessionHandlerProxy {
612
/**
713
* @var string
@@ -26,8 +32,7 @@ public function __construct(\SessionHandlerInterface $handler) {
2632
/**
2733
* {@inheritdoc}
2834
*/
29-
#[HackSupportForSymfony6] public function getId(): string { /*
30-
public function getId() { /**/
35+
public function getId() {
3136
return $this->_sessionId;
3237
}
3338

@@ -41,8 +46,7 @@ public function setId($id) {
4146
/**
4247
* {@inheritdoc}
4348
*/
44-
#[HackSupportForSymfony6] public function getName(): string { /*
45-
public function getName() { /**/
49+
public function getName() {
4650
return $this->_sessionName;
4751
}
4852

@@ -54,3 +58,5 @@ public function setName($name) {
5458
throw new \RuntimeException("Can not change session name in VirtualProxy");
5559
}
5660
}
61+
62+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
namespace Ratchet\Session\Storage\Proxy;
3+
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
4+
5+
/**
6+
* [internal] VirtualProxy for Symfony 6 on PHP 8+ using native types like `getId(): string`
7+
*
8+
* @internal used internally only, should not be referenced directly
9+
* @see VirtualProxy
10+
*/
11+
class VirtualProxyForSymfony6 extends SessionHandlerProxy {
12+
/**
13+
* @var string
14+
*/
15+
protected $_sessionId;
16+
17+
/**
18+
* @var string
19+
*/
20+
protected $_sessionName;
21+
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function __construct(\SessionHandlerInterface $handler) {
26+
parent::__construct($handler);
27+
28+
$this->saveHandlerName = 'user';
29+
$this->_sessionName = ini_get('session.name');
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function getId(): string {
36+
return $this->_sessionId;
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
public function setId($id) {
43+
$this->_sessionId = $id;
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function getName(): string {
50+
return $this->_sessionName;
51+
}
52+
53+
/**
54+
* DO NOT CALL THIS METHOD
55+
* @internal
56+
*/
57+
public function setName($name) {
58+
throw new \RuntimeException("Can not change session name in VirtualProxy");
59+
}
60+
}

src/Ratchet/Session/Storage/VirtualSessionStorage.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
use Ratchet\Session\Storage\Proxy\VirtualProxy;
55
use Ratchet\Session\Serialize\HandlerInterface;
66

7+
if (PHP_VERSION_ID > 80000 && (new \ReflectionMethod('Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage','start'))->hasReturnType()) {
8+
// alias to class for Symfony 6 on PHP 8+ that uses native types like `start(): bool`
9+
class_alias(__NAMESPACE__ . '\\VirtualSessionStorageForSymfony6', __NAMESPACE__ . '\\VirtualSessionStorage');
10+
} else {
11+
// fall back to class without native types
12+
713
class VirtualSessionStorage extends NativeSessionStorage {
814
/**
915
* @var \Ratchet\Session\Serialize\HandlerInterface
@@ -25,8 +31,7 @@ public function __construct(\SessionHandlerInterface $handler, $sessionId, Handl
2531
/**
2632
* {@inheritdoc}
2733
*/
28-
#[HackSupportForSymfony6] public function start(): bool { /*
29-
public function start() { /**/
34+
public function start() {
3035
if ($this->started && !$this->closed) {
3136
return true;
3237
}
@@ -52,8 +57,7 @@ public function start() { /**/
5257
/**
5358
* {@inheritdoc}
5459
*/
55-
#[HackSupportForSymfony6] public function regenerate(bool $destroy = false, ?int $lifetime = null): bool { /*
56-
public function regenerate($destroy = false, $lifetime = null) { /**/
60+
public function regenerate($destroy = false, $lifetime = null) {
5761
// .. ?
5862
return false;
5963
}
@@ -89,3 +93,5 @@ public function setSaveHandler($saveHandler = null) {
8993
$this->saveHandler = $saveHandler;
9094
}
9195
}
96+
97+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
namespace Ratchet\Session\Storage;
3+
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
4+
use Ratchet\Session\Storage\Proxy\VirtualProxy;
5+
use Ratchet\Session\Serialize\HandlerInterface;
6+
7+
/**
8+
* [internal] VirtualSessionStorage for Symfony 6 on PHP 8+ using native types like `start(): bool`
9+
*
10+
* @internal used internally only, should not be referenced directly
11+
* @see VirtualSessionStorage
12+
*/
13+
class VirtualSessionStorageForSymfony6 extends NativeSessionStorage {
14+
/**
15+
* @var \Ratchet\Session\Serialize\HandlerInterface
16+
*/
17+
protected $_serializer;
18+
19+
/**
20+
* @param \SessionHandlerInterface $handler
21+
* @param string $sessionId The ID of the session to retrieve
22+
* @param \Ratchet\Session\Serialize\HandlerInterface $serializer
23+
*/
24+
public function __construct(\SessionHandlerInterface $handler, $sessionId, HandlerInterface $serializer) {
25+
$this->setSaveHandler($handler);
26+
$this->saveHandler->setId($sessionId);
27+
$this->_serializer = $serializer;
28+
$this->setMetadataBag(null);
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function start(): bool {
35+
if ($this->started && !$this->closed) {
36+
return true;
37+
}
38+
39+
// You have to call Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::open() to use
40+
// pdo_sqlite (and possible pdo_*) as session storage, if you are using a DSN string instead of a \PDO object
41+
// in the constructor. The method arguments are filled with the values, which are also used by the symfony
42+
// framework in this case. This must not be the best choice, but it works.
43+
$this->saveHandler->open(session_save_path(), session_name());
44+
45+
$rawData = $this->saveHandler->read($this->saveHandler->getId());
46+
$sessionData = $this->_serializer->unserialize($rawData);
47+
48+
$this->loadSession($sessionData);
49+
50+
if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
51+
$this->saveHandler->setActive(false);
52+
}
53+
54+
return true;
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
public function regenerate(bool $destroy = false, ?int $lifetime = null): bool {
61+
// .. ?
62+
return false;
63+
}
64+
65+
/**
66+
* {@inheritdoc}
67+
*/
68+
public function save() {
69+
// get the data from the bags?
70+
// serialize the data
71+
// save the data using the saveHandler
72+
// $this->saveHandler->write($this->saveHandler->getId(),
73+
74+
if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
75+
$this->saveHandler->setActive(false);
76+
}
77+
78+
$this->closed = true;
79+
}
80+
81+
/**
82+
* {@inheritdoc}
83+
*/
84+
public function setSaveHandler($saveHandler = null) {
85+
if (!($saveHandler instanceof \SessionHandlerInterface)) {
86+
throw new \InvalidArgumentException('Handler must be instance of SessionHandlerInterface');
87+
}
88+
89+
if (!($saveHandler instanceof VirtualProxy)) {
90+
$saveHandler = new VirtualProxy($saveHandler);
91+
}
92+
93+
$this->saveHandler = $saveHandler;
94+
}
95+
}

0 commit comments

Comments
 (0)