summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Database/Database.php98
-rw-r--r--src/Database/DatabaseServiceProvider.php16
-rw-r--r--src/Database/Db.php1
-rw-r--r--src/Database/Migration/Migrate.php40
-rw-r--r--src/Database/Migration/MigrationServiceProvider.php11
-rw-r--r--src/Http/SessionHandlers/AbstractHandler.php75
-rw-r--r--src/Http/SessionHandlers/DatabaseHandler.php108
-rw-r--r--src/Http/SessionServiceProvider.php21
-rw-r--r--src/Models/BaseModel.php16
9 files changed, 359 insertions, 27 deletions
diff --git a/src/Database/Database.php b/src/Database/Database.php
new file mode 100644
index 00000000..407a8bf9
--- /dev/null
+++ b/src/Database/Database.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Engelsystem\Database;
+
+use Illuminate\Database\Connection as DatabaseConnection;
+use PDO;
+
+class Database
+{
+ /** @var DatabaseConnection */
+ protected $connection;
+
+ /**
+ * @param DatabaseConnection $connection
+ */
+ public function __construct(DatabaseConnection $connection)
+ {
+ $this->connection = $connection;
+ }
+
+ /**
+ * Run a select query
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return object[]
+ */
+ public function select($query, array $bindings = [])
+ {
+ return $this->connection->select($query, $bindings);
+ }
+
+ /**
+ * Run a select query and return only the first result or null if no result is found.
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return object|null
+ */
+ public function selectOne($query, array $bindings = [])
+ {
+ return $this->connection->selectOne($query, $bindings);
+ }
+
+ /**
+ * Run an insert query
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return bool
+ */
+ public function insert($query, array $bindings = [])
+ {
+ return $this->connection->insert($query, $bindings);
+ }
+
+ /**
+ * Run an update query
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return int
+ */
+ public function update($query, array $bindings = [])
+ {
+ return $this->connection->update($query, $bindings);
+ }
+
+ /**
+ * Run a delete query
+ *
+ * @param string $query
+ * @param array $bindings
+ * @return int
+ */
+ public function delete($query, array $bindings = [])
+ {
+ return $this->connection->delete($query, $bindings);
+ }
+
+ /**
+ * Get the PDO instance
+ *
+ * @return PDO
+ */
+ public function getPdo()
+ {
+ return $this->connection->getPdo();
+ }
+
+ /**
+ * @return DatabaseConnection
+ */
+ public function getConnection()
+ {
+ return $this->connection;
+ }
+}
diff --git a/src/Database/DatabaseServiceProvider.php b/src/Database/DatabaseServiceProvider.php
index 7328bc4e..b3c33588 100644
--- a/src/Database/DatabaseServiceProvider.php
+++ b/src/Database/DatabaseServiceProvider.php
@@ -5,6 +5,7 @@ namespace Engelsystem\Database;
use Engelsystem\Container\ServiceProvider;
use Exception;
use Illuminate\Database\Capsule\Manager as CapsuleManager;
+use Illuminate\Database\Connection as DatabaseConnection;
use PDOException;
class DatabaseServiceProvider extends ServiceProvider
@@ -30,14 +31,25 @@ class DatabaseServiceProvider extends ServiceProvider
$capsule->bootEloquent();
$capsule->getConnection()->useDefaultSchemaGrammar();
+ $pdo = null;
try {
- $capsule->getConnection()->getPdo();
+ $pdo = $capsule->getConnection()->getPdo();
} catch (PDOException $e) {
$this->exitOnError();
}
- $this->app->instance('db', $capsule);
+ $this->app->instance(CapsuleManager::class, $capsule);
+ $this->app->instance(Db::class, $capsule);
Db::setDbManager($capsule);
+
+ $connection = $capsule->getConnection();
+ $this->app->instance(DatabaseConnection::class, $connection);
+
+ $database = $this->app->make(Database::class);
+ $this->app->instance(Database::class, $database);
+ $this->app->instance('db', $database);
+ $this->app->instance('db.pdo', $pdo);
+ $this->app->instance('db.connection', $connection);
}
/**
diff --git a/src/Database/Db.php b/src/Database/Db.php
index c0871e68..d007f1e5 100644
--- a/src/Database/Db.php
+++ b/src/Database/Db.php
@@ -6,6 +6,7 @@ use Illuminate\Database\Capsule\Manager as CapsuleManager;
use Illuminate\Database\Connection as DatabaseConnection;
use PDO;
+/** @deprecated */
class Db
{
/** @var CapsuleManager */
diff --git a/src/Database/Migration/Migrate.php b/src/Database/Migration/Migrate.php
index 3a08bb6e..9c6d3e43 100644
--- a/src/Database/Migration/Migrate.php
+++ b/src/Database/Migration/Migrate.php
@@ -18,7 +18,7 @@ class Migrate
protected $app;
/** @var SchemaBuilder */
- protected $scheme;
+ protected $schema;
/** @var callable */
protected $output;
@@ -29,13 +29,13 @@ class Migrate
/**
* Migrate constructor
*
- * @param SchemaBuilder $scheme
+ * @param SchemaBuilder $schema
* @param Application $app
*/
- public function __construct(SchemaBuilder $scheme, Application $app)
+ public function __construct(SchemaBuilder $schema, Application $app)
{
$this->app = $app;
- $this->scheme = $scheme;
+ $this->schema = $schema;
$this->output = function () { };
}
@@ -77,6 +77,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
*
* @return Collection
@@ -156,28 +171,13 @@ class Migrate
}
/**
- * Setup migration tables
- */
- protected function initMigration()
- {
- if ($this->scheme->hasTable($this->table)) {
- return;
- }
-
- $this->scheme->create($this->table, function (Blueprint $table) {
- $table->increments('id');
- $table->string('migration');
- });
- }
-
- /**
* Init a table query
*
* @return Builder
*/
protected function getTableQuery()
{
- return $this->scheme->getConnection()->table($this->table);
+ return $this->schema->getConnection()->table($this->table);
}
/**
diff --git a/src/Database/Migration/MigrationServiceProvider.php b/src/Database/Migration/MigrationServiceProvider.php
index 15d06eaf..310b2114 100644
--- a/src/Database/Migration/MigrationServiceProvider.php
+++ b/src/Database/Migration/MigrationServiceProvider.php
@@ -3,16 +3,19 @@
namespace Engelsystem\Database\Migration;
use Engelsystem\Container\ServiceProvider;
-use Engelsystem\Database\Db;
+use Engelsystem\Database\Database;
use Illuminate\Database\Schema\Builder as SchemaBuilder;
class MigrationServiceProvider extends ServiceProvider
{
public function register()
{
- $schema = Db::connection()->getSchemaBuilder();
- $this->app->instance('db.scheme', $schema);
- $this->app->bind(SchemaBuilder::class, 'db.scheme');
+ /** @var Database $database */
+ $database = $this->app->get(Database::class);
+ $schema = $database->getConnection()->getSchemaBuilder();
+
+ $this->app->instance('db.schema', $schema);
+ $this->app->bind(SchemaBuilder::class, 'db.schema');
$migration = $this->app->make(Migrate::class);
$this->app->instance('db.migration', $migration);
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,
+ ]);
}
/**
diff --git a/src/Models/BaseModel.php b/src/Models/BaseModel.php
index cf718e4f..d5ded428 100644
--- a/src/Models/BaseModel.php
+++ b/src/Models/BaseModel.php
@@ -2,6 +2,8 @@
namespace Engelsystem\Models;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
abstract class BaseModel extends Model
@@ -10,6 +12,8 @@ abstract class BaseModel extends Model
public $timestamps = false;
/**
+ * Create a new model
+ *
* @param array $attributes
* @return BaseModel
*/
@@ -20,4 +24,16 @@ abstract class BaseModel extends Model
return $instance;
}
+
+ /**
+ * Find a model by its primary key
+ *
+ * @param mixed $id
+ * @param array $columns
+ * @return Builder|Builder[]|Collection|Model|null
+ */
+ public static function find($id, $columns = ['*'])
+ {
+ return static::query()->find($id, $columns);
+ }
}