123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- <?php
- namespace App\Controllers;
- use App\Database\DB;
- use App\Exceptions\NotFoundException;
- use App\Exceptions\UnauthorizedException;
- use App\Traits\SingletonController;
- use App\Web\Log;
- use App\Web\Session;
- use Flight;
- class UserController extends Controller
- {
- use SingletonController;
- const PER_PAGE = 15;
- public function index($page = 1): void
- {
- $this->checkAdmin();
- $page = max(0, --$page);
- $users = DB::query('SELECT * FROM `users` LIMIT ? OFFSET ?', [self::PER_PAGE, $page * self::PER_PAGE])->fetchAll();
- $pages = DB::query('SELECT COUNT(*) AS `count` FROM `users`')->fetch()->count / self::PER_PAGE;
- Flight::render('user/index.twig', [
- 'users' => $users,
- 'next' => $page < floor($pages),
- 'previous' => $page >= 1,
- 'current_page' => ++$page,
- ]);
- }
- public function create(): void
- {
- $this->checkAdmin();
- Flight::render('user/create.twig');
- }
- public function store(): void
- {
- $this->checkAdmin();
- $form = Flight::request()->data;
- if (!isset($form->email) || empty($form->email)) {
- Session::alert('The email is required.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (!isset($form->username) || empty($form->username)) {
- Session::alert('The username is required.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (DB::query('SELECT COUNT(*) AS `count` FROM `users` WHERE `username` = ?', $form->username)->fetch()->count > 0) {
- Session::alert('The username already taken.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (!isset($form->password) || empty($form->password)) {
- Session::alert('The password is required.', 'danger');
- Flight::redirectBack();
- return;
- }
- do {
- $userCode = substr(md5(microtime()), rand(0, 26), 5);
- } while (DB::query('SELECT COUNT(*) AS `count` FROM `users` WHERE `user_code` = ?', $userCode)->fetch()->count > 0);
- $token = $this->generateNewToken();
- DB::query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`) VALUES (?, ?, ?, ?, ?, ?, ?)', [
- $form->email,
- $form->username,
- password_hash($form->password, PASSWORD_DEFAULT),
- isset($form->is_admin),
- isset($form->is_active),
- $userCode,
- $token
- ]);
- Session::alert("User '$form->username' created!", 'success');
- Log::info('User ' . Session::get('username') . ' created a new user.', [array_diff($form->getData(), ['password'])]);
- Flight::redirect('/users');
- }
- public function edit($id): void
- {
- $this->checkAdmin();
- $user = DB::query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $id)->fetch();
- if (!$user) {
- Flight::error(new NotFoundException());
- return;
- }
- Flight::render('user/edit.twig', [
- 'user' => $user
- ]);
- }
- public function update($id): void
- {
- $this->checkAdmin();
- $form = Flight::request()->data;
- $user = DB::query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $id)->fetch();
- if (!$user) {
- Flight::error(new NotFoundException());
- return;
- }
- if (!isset($form->email) || empty($form->email)) {
- Session::alert('The email is required.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (!isset($form->username) || empty($form->username)) {
- Session::alert('The username is required.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (DB::query('SELECT COUNT(*) AS `count` FROM `users` WHERE `username` = ? AND `username` <> ?', [$form->username, $user->username])->fetch()->count > 0) {
- Session::alert('The username already taken.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (isset($form->password) && !empty($form->password)) {
- DB::query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=? WHERE `id` = ?', [
- $form->email,
- $form->username,
- password_hash($form->password, PASSWORD_DEFAULT),
- isset($form->is_admin),
- isset($form->is_active),
- $user->id
- ]);
- } else {
- DB::query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=? WHERE `id` = ?', [
- $form->email,
- $form->username,
- isset($form->is_admin),
- isset($form->is_active),
- $user->id
- ]);
- }
- Session::alert("User '$form->username' updated!", 'success');
- Log::info('User ' . Session::get('username') . " updated $user->id.", [$user, array_diff($form->getData(), ['password'])]);
- Flight::redirect('/users');
- }
- public function delete($id): void
- {
- $this->checkAdmin();
- $user = DB::query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $id)->fetch();
- if (!$user) {
- Flight::error(new NotFoundException());
- return;
- }
- if ($user->id === Session::get('user_id')) {
- Session::alert('You cannot delete yourself.', 'danger');
- Flight::redirectBack();
- return;
- }
- DB::query('DELETE FROM `users` WHERE `id` = ?', $user->id);
- Session::alert('User deleted.', 'success');
- Log::info('User ' . Session::get('username') . " deleted $user->id.");
- Flight::redirect('/users');
- }
- public function profile(): void
- {
- $this->checkLogin();
- $user = DB::query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', Session::get('user_id'))->fetch();
- if (!$user) {
- Flight::error(new NotFoundException());
- return;
- }
- if ($user->id !== Session::get('user_id') && !Session::get('admin', false)) {
- Flight::error(new UnauthorizedException());
- return;
- }
- Flight::render('user/profile.twig', [
- 'user' => $user
- ]);
- }
- public function profileEdit($id): void
- {
- $this->checkLogin();
- $form = Flight::request()->data;
- $user = DB::query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $id)->fetch();
- if (!$user) {
- Flight::error(new NotFoundException());
- return;
- }
- if ($user->id !== Session::get('user_id') && !Session::get('admin', false)) {
- Flight::error(new UnauthorizedException());
- return;
- }
- if (!isset($form->email) || empty($form->email)) {
- Session::alert('The email is required.', 'danger');
- Flight::redirectBack();
- return;
- }
- if (isset($form->password) && !empty($form->password)) {
- DB::query('UPDATE `users` SET `email`=?, `password`=? WHERE `id` = ?', [
- $form->email,
- password_hash($form->password, PASSWORD_DEFAULT),
- $user->id
- ]);
- } else {
- DB::query('UPDATE `users` SET `email`=? WHERE `id` = ?', [
- $form->email,
- $user->id
- ]);
- }
- Session::alert('Profile updated successfully!', 'success');
- Log::info('User ' . Session::get('username') . " updated profile of $user->id.");
- Flight::redirectBack();
- }
- public function refreshToken($id): void
- {
- $this->checkLogin();
- $user = DB::query('SELECT * FROM `users` WHERE `id` = ? LIMIT 1', $id)->fetch();
- if (!$user) {
- Flight::halt(404);
- return;
- }
- if ($user->id !== Session::get('user_id') && !Session::get('admin', false)) {
- Flight::halt(403);
- return;
- }
- $token = $this->generateNewToken();
- DB::query('UPDATE `users` SET `token`=? WHERE `id` = ?', [
- $token,
- $user->id
- ]);
- Log::info('User ' . Session::get('username') . " refreshed token of user $user->id.");
- echo $token;
- }
- protected function generateNewToken(): string
- {
- do {
- $token = 'token_' . md5(uniqid('', true));
- } while (DB::query('SELECT COUNT(*) AS `count` FROM `users` WHERE `token` = ?', $token)->fetch()->count > 0);
- return $token;
- }
- }
|