diff --git a/CHANGELOG.md b/CHANGELOG.md index 391d95e..bbbee2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ -## v2.0 [WIP] +## v2.0 + Migrated from Flight to Slim 3 framework. + Added install wizard (using the CLI is no longer required). + Allow discord bot to display the preview. ++ Theme switcher on the web UI. ++ Added used space indicator per user. ++ MySQL support. + Improvements under the hood. ## v1.3 diff --git a/app/Controllers/Controller.php b/app/Controllers/Controller.php index 1df56e0..9f07e97 100644 --- a/app/Controllers/Controller.php +++ b/app/Controllers/Controller.php @@ -4,6 +4,7 @@ namespace App\Controllers; use League\Flysystem\Adapter\Local; +use League\Flysystem\FileNotFoundException; use League\Flysystem\Filesystem; use Slim\Container; use Slim\Http\Request; @@ -59,7 +60,7 @@ abstract class Controller /** * @param $path */ - public function removeDirectory($path) + protected function removeDirectory($path) { $files = glob($path . '/*'); foreach ($files as $file) { @@ -68,4 +69,25 @@ abstract class Controller rmdir($path); return; } + + /** + * @param $id + * @return int + */ + protected function getUsedSpaceByUser($id): int + { + $medias = $this->database->query('SELECT `uploads`.`storage_path` FROM `uploads` WHERE `user_id` = ?', $id)->fetchAll(); + + $totalSize = 0; + + $filesystem = $this->getStorage(); + foreach ($medias as $media) { + try { + $totalSize += $filesystem->getSize($media->storage_path); + } catch (FileNotFoundException $e) { + } + } + + return $totalSize; + } } \ No newline at end of file diff --git a/app/Controllers/DashboardController.php b/app/Controllers/DashboardController.php index f6f7410..d9a7cc4 100644 --- a/app/Controllers/DashboardController.php +++ b/app/Controllers/DashboardController.php @@ -23,6 +23,7 @@ class DashboardController extends Controller { if ($request->getParam('afterInstall') !== null && is_dir('install')) { + Session::alert('Installation completed successfully!', 'success'); $this->removeDirectory('install'); } @@ -101,7 +102,33 @@ class DashboardController extends Controller 'mediasCount' => $mediasCount, 'orphanFilesCount' => $orphanFilesCount, 'totalSize' => $this->humanFilesize($totalSize), - 'max_filesize' => ini_get('post_max_size') . '/' . ini_get('upload_max_filesize'), + 'post_max_size' => ini_get('post_max_size'), + 'upload_max_filesize' => ini_get('upload_max_filesize'), ]); } + + /** + * @param Request $request + * @param Response $response + * @return Response + */ + public function getThemes(Request $request, Response $response): Response + { + $apiJson = json_decode(file_get_contents('https://bootswatch.com/api/4.json')); + + $out = []; + + foreach ($apiJson->themes as $theme) { + $out["{$theme->name} - {$theme->description}"] = $theme->cssMin; + } + + return $response->withJson($out); + } + + + public function applyTheme(Request $request, Response $response): Response + { + file_put_contents('static/bootstrap/css/bootstrap.min.css', file_get_contents($request->getParam('css'))); + return $response->withRedirect('/system')->withAddedHeader('Cache-Control', 'no-cache, must-revalidate'); + } } \ No newline at end of file diff --git a/app/Controllers/LoginController.php b/app/Controllers/LoginController.php index 1596094..2234bb6 100644 --- a/app/Controllers/LoginController.php +++ b/app/Controllers/LoginController.php @@ -48,6 +48,7 @@ class LoginController extends Controller Session::set('user_id', $result->id); Session::set('username', $result->username); Session::set('admin', $result->is_admin); + Session::set('used_space', $this->humanFilesize($this->getUsedSpaceByUser($result->id))); Session::alert("Welcome, $result->username!", 'info'); $this->logger->info("User $result->username logged in."); diff --git a/app/Controllers/UploadController.php b/app/Controllers/UploadController.php index 1dad526..f109fc7 100644 --- a/app/Controllers/UploadController.php +++ b/app/Controllers/UploadController.php @@ -60,7 +60,7 @@ class UploadController extends Controller $user->id, $code, $file->getClientFilename(), - $storagePath + $storagePath, ]); $base_url = $this->settings['base_url']; @@ -104,7 +104,7 @@ class UploadController extends Controller $type = explode('/', $mime)[0]; if ($type === 'text') { $media->text = $filesystem->read($media->storage_path); - } elseif (in_array($type, ['image', 'video']) && $request->getHeaderLine('Scheme') === 'HTTP/2.0') { + } else if (in_array($type, ['image', 'video']) && $request->getHeaderLine('Scheme') === 'HTTP/2.0') { $response = $response->withHeader('Link', "<{$this->settings['base_url']}/$args[userCode]/$args[mediaCode]/raw>; rel=preload; as={$type}"); } @@ -115,7 +115,7 @@ class UploadController extends Controller return $this->view->render($response, 'upload/public.twig', [ 'media' => $media, 'type' => $mime, - 'extension' => pathinfo($media->filename, PATHINFO_EXTENSION) + 'extension' => pathinfo($media->filename, PATHINFO_EXTENSION), ]); } } @@ -196,7 +196,7 @@ class UploadController extends Controller throw new NotFoundException($request, $response); } - $this->database->query('UPDATE `uploads` SET `published`=? WHERE `id`=?', [!$media->published, $media->id]); + $this->database->query('UPDATE `uploads` SET `published`=? WHERE `id`=?', [$media->published ? 0 : 1, $media->id]); return $response->withStatus(200); } @@ -223,6 +223,7 @@ class UploadController extends Controller } finally { $this->database->query('DELETE FROM `uploads` WHERE `id` = ?', $args['id']); $this->logger->info('User ' . Session::get('username') . ' deleted a media.', [$args['id']]); + Session::set('used_space', $this->humanFilesize($this->getUsedSpaceByUser(Session::get('user_id')))); } } else { throw new UnauthorizedException(); @@ -242,7 +243,7 @@ class UploadController extends Controller $media = $this->database->query('SELECT * FROM `uploads` INNER JOIN `users` ON `uploads`.`user_id` = `users`.`id` WHERE `user_code` = ? AND `uploads`.`code` = ? LIMIT 1', [ $userCode, - $mediaCode + $mediaCode, ])->fetch(); return $media; diff --git a/app/Database/DB.php b/app/Database/DB.php index e199b3b..5483e8f 100644 --- a/app/Database/DB.php +++ b/app/Database/DB.php @@ -45,7 +45,12 @@ class DB $parameters = [$parameters]; } $query = $this->pdo->prepare($query); - $query->execute($parameters); + + foreach ($parameters as $index => $parameter) { + $query->bindValue($index + 1, $parameter, is_int($parameter) ? PDO::PARAM_INT : PDO::PARAM_STR); + } + + $query->execute(); return $query; } diff --git a/app/routes.php b/app/routes.php index c640c66..f3f1d72 100644 --- a/app/routes.php +++ b/app/routes.php @@ -3,6 +3,8 @@ $app->group('', function () { $this->get('/home[/page/{page}]', \App\Controllers\DashboardController::class . ':home'); $this->get('/system', \App\Controllers\DashboardController::class . ':system')->add(\App\Middleware\AdminMiddleware::class); + $this->get('/system/themes', \App\Controllers\DashboardController::class . ':getThemes')->add(\App\Middleware\AdminMiddleware::class); + $this->post('/system/theme/apply', \App\Controllers\DashboardController::class . ':applyTheme')->add(\App\Middleware\AdminMiddleware::class); $this->group('', function () { $this->get('/users[/page/{page}]', \App\Controllers\UserController::class . ':index'); diff --git a/bin/clean b/bin/clean index 2bb9974..97ed9b8 100644 --- a/bin/clean +++ b/bin/clean @@ -1,7 +1,7 @@ #!/usr/bin/env php 'XBackBone', diff --git a/install/index.php b/install/index.php index b11b397..fd84139 100644 --- a/install/index.php +++ b/install/index.php @@ -60,8 +60,8 @@ $app->post('/', function (Request $request, Response $response) use (&$config) { $config['displayErrorDetails'] = false; $config['db']['connection'] = $request->getParam('connection'); $config['db']['dsn'] = $request->getParam('dsn'); - $config['db']['username'] = null; - $config['db']['password'] = null; + $config['db']['username'] = $request->getParam('db_user'); + $config['db']['password'] = $request->getParam('db_password'); file_put_contents(__DIR__ . '/../config.php', 'post('/', function (Request $request, Response $response) use (&$config) { DB::query("INSERT INTO `users` (`email`, `username`, `password`, `is_admin`, `user_code`) VALUES (?, 'admin', ?, 1, ?)", [$request->getParam('email'), password_hash($request->getParam('password'), PASSWORD_DEFAULT), substr(md5(microtime()), rand(0, 26), 5)]); - Session::alert('Installation completed successfully!', 'success'); return $response->withRedirect('../?afterInstall=true'); }); diff --git a/install/templates/install.twig b/install/templates/install.twig index ca6685e..38689ef 100644 --- a/install/templates/install.twig +++ b/install/templates/install.twig @@ -51,7 +51,8 @@