Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f8cb980

Browse files
committed
[Http-Foundation][Session]feat: create automatically session table with pdo connection
1 parent 929d5f4 commit f8cb980

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\Doctrine\SchemaListener;
4+
5+
use Doctrine\Common\EventSubscriber;
6+
use Doctrine\DBAL\Exception;
7+
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
8+
use Doctrine\ORM\Tools\ToolEvents;
9+
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
10+
11+
class PdoSessionHandlerSchemaSubscriber implements EventSubscriber
12+
{
13+
private PdoSessionHandler $pdoSessionHandler;
14+
15+
/**
16+
* @param PdoSessionHandler $pdoSessionHandler
17+
*/
18+
public function __construct(PdoSessionHandler $pdoSessionHandler)
19+
{
20+
$this->pdoSessionHandler = $pdoSessionHandler;
21+
}
22+
23+
/**
24+
* @throws Exception
25+
*/
26+
public function postGenerateSchema(GenerateSchemaEventArgs $event): void
27+
{
28+
$dbalConnection = $event->getEntityManager()->getConnection();
29+
$this->pdoSessionHandler->configureSchema($event->getSchema(), $dbalConnection);
30+
}
31+
32+
public function getSubscribedEvents(): array
33+
{
34+
$subscribedEvents = [];
35+
36+
if (class_exists(ToolEvents::class)) {
37+
$subscribedEvents[] = ToolEvents::postGenerateSchema;
38+
}
39+
40+
return $subscribedEvents;
41+
}
42+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Symfony\Bridge\Doctrine\Tests\SchemaListener;
4+
5+
use Doctrine\DBAL\Connection;
6+
use Doctrine\DBAL\Schema\Schema;
7+
use Doctrine\ORM\EntityManagerInterface;
8+
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
9+
use PHPUnit\Framework\TestCase;
10+
use Symfony\Bridge\Doctrine\SchemaListener\PdoSessionHandlerSchemaSubscriber;
11+
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
12+
13+
class PdoSessionHandlerSchemaSubscriberTest extends TestCase
14+
{
15+
public function testPostGenerateSchemaPdo()
16+
{
17+
$schema = new Schema();
18+
$dbalConnection = $this->createMock(Connection::class);
19+
$entityManager = $this->createMock(EntityManagerInterface::class);
20+
$entityManager->expects($this->once())
21+
->method('getConnection')
22+
->willReturn($dbalConnection);
23+
$event = new GenerateSchemaEventArgs($entityManager, $schema);
24+
25+
$pdoSessionHandler = $this->createMock(PdoSessionHandler::class);
26+
$pdoSessionHandler->expects($this->once())
27+
->method('configureSchema')
28+
->with($schema, $dbalConnection);
29+
30+
$subscriber = new PdoSessionHandlerSchemaSubscriber($pdoSessionHandler);
31+
$subscriber->postGenerateSchema($event);
32+
}
33+
}

src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
1313

14+
use Doctrine\DBAL\Connection;
15+
use Doctrine\DBAL\Exception;
16+
use Doctrine\DBAL\Schema\AbstractSchemaManager;
17+
use Doctrine\DBAL\Schema\Schema;
18+
use Doctrine\DBAL\Schema\SchemaException;
19+
use Doctrine\DBAL\Types\Types;
20+
1421
/**
1522
* Session handler using a PDO connection to read and write data.
1623
*
@@ -175,6 +182,93 @@ public function __construct(\PDO|string $pdoOrDsn = null, array $options = [])
175182
$this->ttl = $options['ttl'] ?? null;
176183
}
177184

185+
/**
186+
* @param AbstractSchemaManager $schemaManager
187+
*
188+
* @return bool
189+
* @throws Exception
190+
*/
191+
private function isInListTablesWithoutFilter(AbstractSchemaManager $schemaManager) : bool
192+
{
193+
$tablesName = $schemaManager->listTableNames();
194+
195+
if (in_array($this->table, $tablesName)) {
196+
return true;
197+
}
198+
199+
return false;
200+
}
201+
202+
/**
203+
* @throws Exception
204+
*/
205+
public function configureSchema(Schema $schema, Connection $connection): void
206+
{
207+
$configuration = $connection->getConfiguration();
208+
209+
$schemaManager = method_exists(Connection::class, 'createSchemaManager')
210+
? $connection->createSchemaManager()
211+
: $connection->getSchemaManager();
212+
213+
$configuration->setSchemaAssetsFilter(null);
214+
$isTableFound = $this->isInListTablesWithoutFilter($schemaManager);
215+
216+
if ($isTableFound) {
217+
return;
218+
}
219+
220+
$this->addTableToSchema($schema);
221+
}
222+
223+
/**
224+
* @param Schema $schema
225+
*
226+
* @throws SchemaException
227+
*/
228+
private function addTableToSchema(Schema $schema)
229+
{
230+
$this->getConnection();
231+
232+
$table = $schema->createTable($this->table);
233+
switch ($this->driver) {
234+
case 'mysql':
235+
$table->addColumn($this->idCol, Types::BINARY)->setLength(128)->setNotnull(true);
236+
$table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
237+
$table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
238+
$table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
239+
$table->addOption('collate', 'utf8mb4_bin');
240+
$table->addOption('engine', 'InnoDB');
241+
break;
242+
case 'sqlite':
243+
$table->addColumn($this->idCol, Types::TEXT)->setNotnull(true);
244+
$table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
245+
$table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true);
246+
$table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true);
247+
break;
248+
case 'pgsql':
249+
$table->addColumn($this->idCol, Types::STRING)->setLength(128)->setNotnull(true);
250+
$table->addColumn($this->dataCol, Types::BINARY)->setNotnull(true);
251+
$table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true);
252+
$table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true);
253+
break;
254+
case 'oci':
255+
$table->addColumn($this->idCol, Types::STRING)->setLength(128)->setNotnull(true);
256+
$table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
257+
$table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true);
258+
$table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true);
259+
break;
260+
case 'sqlsrv':
261+
$table->addColumn($this->idCol, Types::TEXT)->setLength(128)->setNotnull(true);
262+
$table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
263+
$table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
264+
$table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
265+
break;
266+
default:
267+
throw new \DomainException(sprintf('Creating the session table is currently not implemented for PDO driver "%s".', $this->driver));
268+
}
269+
$table->setPrimaryKey([$this->idCol]);
270+
}
271+
178272
/**
179273
* Creates the table to store sessions which can be called once for setup.
180274
*

0 commit comments

Comments
 (0)