diff options
author | Igor Scheller <igor.scheller@igorshp.de> | 2018-09-30 19:31:14 +0200 |
---|---|---|
committer | Igor Scheller <igor.scheller@igorshp.de> | 2018-09-30 19:33:14 +0200 |
commit | b46207f91176cf944284c01c213d3f69075377a4 (patch) | |
tree | 3d04a46c84c8b66b2d5a56a851249fde80257e28 /src/Http | |
parent | 6187eed3bb08f200050a3078bd762b5731dfbe78 (diff) | |
parent | 0b0890f425ced27b2204a046296de4cccdac4eb8 (diff) |
Merge remote-tracking branch 'MyIgel/session'
Diffstat (limited to 'src/Http')
-rw-r--r-- | src/Http/SessionHandlers/AbstractHandler.php | 75 | ||||
-rw-r--r-- | src/Http/SessionHandlers/DatabaseHandler.php | 108 | ||||
-rw-r--r-- | src/Http/SessionServiceProvider.php | 21 |
3 files changed, 203 insertions, 1 deletions
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 @@ +<?php + +namespace Engelsystem\Http\SessionHandlers; + +use SessionHandlerInterface; + +abstract class AbstractHandler implements SessionHandlerInterface +{ + /** @var string */ + protected $name; + + /** @var string */ + protected $sessionPath; + + /** + * Bootstrap the session handler + * + * @param string $sessionPath + * @param string $name + * @return bool + */ + public function open($sessionPath, $name): bool + { + $this->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 @@ +<?php + +namespace Engelsystem\Http\SessionHandlers; + +use Engelsystem\Database\Database; +use Illuminate\Database\Query\Builder as QueryBuilder; + +class DatabaseHandler extends AbstractHandler +{ + /** @var Database */ + protected $database; + + /** + * @param Database $database + */ + public function __construct(Database $database) + { + $this->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 59121a3b..c2e09624 100644 --- a/src/Http/SessionServiceProvider.php +++ b/src/Http/SessionServiceProvider.php @@ -2,7 +2,9 @@ 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\MockArraySessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; @@ -38,7 +40,24 @@ class SessionServiceProvider extends ServiceProvider return $this->app->make(MockArraySessionStorage::class); } - return $this->app->make(NativeSessionStorage::class, ['options' => ['cookie_httponly' => true]]); + /** @var Config $config */ + $config = $this->app->get('config'); + $sessionConfig = $config->get('session'); + + $handler = null; + switch ($sessionConfig['driver']) { + case 'pdo': + $handler = $this->app->make(DatabaseHandler::class); + break; + } + + return $this->app->make(NativeSessionStorage::class, [ + 'options' => [ + 'cookie_httponly' => true, + 'name' => $sessionConfig['name'], + ], + 'handler' => $handler, + ]); } /** |