summaryrefslogtreecommitdiff
path: root/src/Http
diff options
context:
space:
mode:
authorIgor Scheller <igor.scheller@igorshp.de>2018-09-16 14:08:09 +0200
committerIgor Scheller <igor.scheller@igorshp.de>2018-09-25 14:02:55 +0200
commit0b0890f425ced27b2204a046296de4cccdac4eb8 (patch)
tree5b7a697185ca543ef9c0f0959532dfe8bfb9e3f1 /src/Http
parent104e4f4c437376eb739dd3ef2de603855947a557 (diff)
Session: Added DatabaseHandler, replaces Symfony PdoSessionHandler
Diffstat (limited to 'src/Http')
-rw-r--r--src/Http/SessionHandlers/AbstractHandler.php75
-rw-r--r--src/Http/SessionHandlers/DatabaseHandler.php108
-rw-r--r--src/Http/SessionServiceProvider.php17
3 files changed, 186 insertions, 14 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 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;
}