From 0b0890f425ced27b2204a046296de4cccdac4eb8 Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Sun, 16 Sep 2018 14:08:09 +0200 Subject: Session: Added DatabaseHandler, replaces Symfony PdoSessionHandler --- src/Database/Migration/Migrate.php | 30 ++++---- src/Http/SessionHandlers/AbstractHandler.php | 75 +++++++++++++++++++ src/Http/SessionHandlers/DatabaseHandler.php | 108 +++++++++++++++++++++++++++ src/Http/SessionServiceProvider.php | 17 +---- 4 files changed, 201 insertions(+), 29 deletions(-) create mode 100644 src/Http/SessionHandlers/AbstractHandler.php create mode 100644 src/Http/SessionHandlers/DatabaseHandler.php (limited to 'src') diff --git a/src/Database/Migration/Migrate.php b/src/Database/Migration/Migrate.php index cec8bc4a..9c6d3e43 100644 --- a/src/Database/Migration/Migrate.php +++ b/src/Database/Migration/Migrate.php @@ -76,6 +76,21 @@ class Migrate } } + /** + * Setup migration tables + */ + public function initMigration() + { + if ($this->schema->hasTable($this->table)) { + return; + } + + $this->schema->create($this->table, function (Blueprint $table) { + $table->increments('id'); + $table->string('migration'); + }); + } + /** * Get all migrated migrations * @@ -155,21 +170,6 @@ class Migrate return glob($dir . '/*_*.php'); } - /** - * Setup migration tables - */ - protected function initMigration() - { - if ($this->schema->hasTable($this->table)) { - return; - } - - $this->schema->create($this->table, function (Blueprint $table) { - $table->increments('id'); - $table->string('migration'); - }); - } - /** * Init a table query * diff --git a/src/Http/SessionHandlers/AbstractHandler.php b/src/Http/SessionHandlers/AbstractHandler.php new file mode 100644 index 00000000..135d0d43 --- /dev/null +++ b/src/Http/SessionHandlers/AbstractHandler.php @@ -0,0 +1,75 @@ +name = $name; + $this->sessionPath = $sessionPath; + + return true; + } + + /** + * Shutdown the session handler + * + * @return bool + */ + public function close(): bool + { + return true; + } + + /** + * Remove old sessions + * + * @param int $maxLifetime + * @return bool + */ + public function gc($maxLifetime): bool + { + return true; + } + + /** + * Read session data + * + * @param string $id + * @return string + */ + abstract public function read($id): string; + + /** + * Write session data + * + * @param string $id + * @param string $data + * @return bool + */ + abstract public function write($id, $data): bool; + + /** + * Delete a session + * + * @param string $id + * @return bool + */ + abstract public function destroy($id): bool; +} diff --git a/src/Http/SessionHandlers/DatabaseHandler.php b/src/Http/SessionHandlers/DatabaseHandler.php new file mode 100644 index 00000000..8df70287 --- /dev/null +++ b/src/Http/SessionHandlers/DatabaseHandler.php @@ -0,0 +1,108 @@ +database = $database; + } + + /** + * {@inheritdoc} + */ + public function read($id): string + { + $session = $this->getQuery() + ->where('id', '=', $id) + ->first(); + + return $session ? $session->payload : ''; + } + + /** + * {@inheritdoc} + */ + public function write($id, $data): bool + { + $values = [ + 'payload' => $data, + 'last_activity' => $this->getCurrentTimestamp(), + ]; + + $session = $this->getQuery() + ->where('id', '=', $id) + ->first(); + + if (!$session) { + return $this->getQuery() + ->insert($values + [ + 'id' => $id, + ]); + } + + $this->getQuery() + ->where('id', '=', $id) + ->update($values); + + // The update return can't be used directly because it won't change if the second call is in the same second + return true; + } + + /** + * {@inheritdoc} + */ + public function destroy($id): bool + { + $this->getQuery() + ->where('id', '=', $id) + ->delete(); + + return true; + } + + /** + * {@inheritdoc} + */ + public function gc($maxLifetime): bool + { + $timestamp = $this->getCurrentTimestamp(-$maxLifetime); + + $this->getQuery() + ->where('last_activity', '<', $timestamp) + ->delete(); + + return true; + } + + /** + * @return QueryBuilder + */ + protected function getQuery(): QueryBuilder + { + return $this->database + ->getConnection() + ->table('sessions'); + } + + /** + * Format the SQL timestamp + * + * @param int $diff + * @return string + */ + protected function getCurrentTimestamp(int $diff = 0): string + { + return date('Y-m-d H:i:s', strtotime(sprintf('%+d seconds', $diff))); + } +} diff --git a/src/Http/SessionServiceProvider.php b/src/Http/SessionServiceProvider.php index 66ff18cc..c2e09624 100644 --- a/src/Http/SessionServiceProvider.php +++ b/src/Http/SessionServiceProvider.php @@ -4,8 +4,8 @@ namespace Engelsystem\Http; use Engelsystem\Config\Config; use Engelsystem\Container\ServiceProvider; +use Engelsystem\Http\SessionHandlers\DatabaseHandler; use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface; @@ -45,20 +45,9 @@ class SessionServiceProvider extends ServiceProvider $sessionConfig = $config->get('session'); $handler = null; - $driver = $sessionConfig['driver']; - - switch ($driver) { + switch ($sessionConfig['driver']) { case 'pdo': - $handler = $this->app->make(PdoSessionHandler::class, [ - 'pdoOrDsn' => $this->app->get('db.pdo'), - 'options' => [ - 'db_table' => 'sessions', - 'db_id_col' => 'id', - 'db_data_col' => 'payload', - 'db_lifetime_col' => 'lifetime', - 'db_time_col' => 'last_activity', - ], - ]); + $handler = $this->app->make(DatabaseHandler::class); break; } -- cgit v1.2.3-54-g00ecf