1
0
mirror of https://github.com/chylex/Lightning-Tracker.git synced 2025-05-24 23:34:08 +02:00

Minor fixes (code formatting, unused elements, future TODOs)

This commit is contained in:
chylex 2020-08-06 14:57:49 +02:00
parent ab75ece64c
commit ae25051aa8
28 changed files with 74 additions and 61 deletions

View File

@ -1,11 +1,11 @@
CREATE TABLE `system_role_perms` (
`role_id` SMALLINT NOT NULL,
`permission` ENUM (
'settings',
'trackers.list',
'trackers.list.hidden',
'trackers.add',
'trackers.edit',
'settings',
'trackers.list',
'trackers.list.hidden',
'trackers.add',
'trackers.edit',
'users.list',
'users.list.email',
'users.add',

View File

@ -1,9 +1,9 @@
CREATE TABLE `trackers` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`url` VARCHAR(32) NOT NULL,
`owner_id` INT NOT NULL,
`hidden` BOOL NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`url` VARCHAR(32) NOT NULL,
`owner_id` INT NOT NULL,
`hidden` BOOL NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`url`),
FOREIGN KEY (`owner_id`)

View File

@ -6,8 +6,8 @@ CREATE TABLE `user_logins` (
UNIQUE KEY (`token`),
FOREIGN KEY (`id`)
REFERENCES `users` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE utf8mb4_general_ci

View File

@ -1,4 +1,4 @@
CREATE TABLE IF NOT EXISTS `users` (
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`email` VARCHAR(255) NOT NULL,

View File

@ -15,6 +15,7 @@ abstract class AbstractTable{
/**
* Fetches the next result.
*
* @param PDOStatement $stmt
* @return mixed
*/
@ -24,6 +25,7 @@ abstract class AbstractTable{
/**
* Fetches the next result.
*
* @param PDOStatement $stmt
* @return mixed
*/
@ -33,6 +35,7 @@ abstract class AbstractTable{
/**
* Fetches one result and closes the cursor.
*
* @param PDOStatement $stmt
* @return mixed
*/
@ -44,6 +47,7 @@ abstract class AbstractTable{
/**
* Fetches one result and closes the cursor.
*
* @param PDOStatement $stmt
* @return mixed
*/

View File

@ -11,7 +11,7 @@ final class DB{
SET time_zone = "+00:00",
sql_mode = "STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION"
SQL;
/**
* @return PDO
* @throws PDOException

View File

@ -18,10 +18,6 @@ final class RoleInfo{
return $this->id;
}
public function getTitle(): string{
return $this->title;
}
public function getTitleSafe(): string{
return protect($this->title);
}

View File

@ -10,14 +10,14 @@ final class UserInfo{
private string $name;
private string $email;
private ?string $role_title;
private string $registration_date;
private string $date_registered;
public function __construct(int $id, string $name, string $email, ?string $role_title, string $registration_date){
public function __construct(int $id, string $name, string $email, ?string $role_title, string $date_registered){
$this->id = $id;
$this->name = $name;
$this->email = $email;
$this->role_title = $role_title;
$this->registration_date = $registration_date;
$this->date_registered = $date_registered;
}
public function getId(): int{
@ -37,7 +37,7 @@ final class UserInfo{
}
public function getRegistrationDate(): string{
return $this->registration_date;
return $this->date_registered;
}
}

View File

@ -13,7 +13,7 @@ final class UserLoginInfo{
*/
public static function hashPassword(string $password): string{
$hash = password_hash($password, PASSWORD_BCRYPT);
if (!$hash){
throw new Exception('Fatal error, hashing function failed.');
}

View File

@ -3,11 +3,10 @@ declare(strict_types = 1);
namespace Database\Tables;
use Database\Tables\Traits\PermTable;
use Database\AbstractTable;
use Database\DB;
use Database\Objects\RoleInfo;
use Database\Objects\UserProfile;
use Database\Tables\Traits\PermTable;
use PDO;
use PDOException;

View File

@ -87,9 +87,9 @@ SQL;
}
public function removeUserId(int $user_id){
$stmt = $this->db->prepare('DELETE FROM tracker_members WHERE tracker_id = ? AND user_id = ?');
$stmt->bindValue(1, $this->getTrackerId(), PDO::PARAM_INT);
$stmt->bindValue(2, $user_id, PDO::PARAM_INT);
$stmt = $this->db->prepare('DELETE FROM tracker_members WHERE user_id = ? AND tracker_id = ?');
$stmt->bindValue(1, $user_id, PDO::PARAM_INT);
$stmt->bindValue(2, $this->getTrackerId(), PDO::PARAM_INT);
$stmt->execute();
}
}

View File

@ -3,11 +3,11 @@ declare(strict_types = 1);
namespace Database\Tables;
use Database\Tables\Traits\PermTable;
use Database\AbstractTrackerTable;
use Database\Objects\RoleInfo;
use Database\Objects\TrackerInfo;
use Database\Objects\UserProfile;
use Database\Tables\Traits\PermTable;
use PDO;
use PDOException;

View File

@ -69,7 +69,7 @@ final class TrackerTable extends AbstractTable{
$stmt->execute();
}
public function countTrackers(TrackerFilter $filter = null): ?int{
public function countTrackers(?TrackerFilter $filter = null): ?int{
$filter ??= TrackerFilter::empty();
$stmt = $this->db->prepare('SELECT COUNT(*) FROM trackers '.$filter->generateClauses(true));
@ -84,7 +84,7 @@ final class TrackerTable extends AbstractTable{
* @param TrackerFilter|null $filter
* @return TrackerInfo[]
*/
public function listTrackers(TrackerFilter $filter = null): array{
public function listTrackers(?TrackerFilter $filter = null): array{
$filter ??= TrackerFilter::empty();
$stmt = $this->db->prepare('SELECT id, name, url, owner_id FROM trackers '.$filter->generateClauses());

View File

@ -19,11 +19,11 @@ trait PermTable{
$values = implode(',', array_map(fn($ignore): string => '(LAST_INSERT_ID(), ?)', $perms));
$stmt = $this->db->prepare(str_replace('()', $values, $sql_base));
for($i = 0, $count = count($perms); $i < $count; $i++){
$stmt->bindValue($i + 1, $perms[$i]);
}
$stmt->execute();
}
@ -33,11 +33,11 @@ trait PermTable{
*/
protected final function fetchRoles(PDOStatement $stmt): array{
$results = [];
while(($res = $this->fetchNext($stmt)) !== false){
$results[] = new RoleInfo($res['id'], $res['title']);
}
return $results;
}
@ -47,11 +47,11 @@ trait PermTable{
*/
protected final function fetchPerms(PDOStatement $stmt): array{
$results = [];
while(($res = $this->fetchNextColumn($stmt)) !== false){
$results[] = $res;
}
return $results;
}
}

View File

@ -41,7 +41,7 @@ final class UserTable extends AbstractTable{
$stmt->execute();
}
public function countUsers(UserFilter $filter = null): ?int{
public function countUsers(?UserFilter $filter = null): ?int{
$filter ??= UserFilter::empty();
$stmt = $this->db->prepare('SELECT COUNT(*) FROM users '.$filter->generateClauses(true));
@ -56,7 +56,7 @@ final class UserTable extends AbstractTable{
* @param UserFilter|null $filter
* @return UserInfo[]
*/
public function listUsers(UserFilter $filter = null): array{
public function listUsers(?UserFilter $filter = null): array{
$filter ??= UserFilter::empty();
$sql = <<<SQL

View File

@ -75,7 +75,7 @@ HTML;
echo '<option value="'.$option[0].'"'.$class.$selected.'>'.$option[1].'</option>';
}
echo <<<HTML
echo <<<HTML
</select>
HTML;

View File

@ -136,6 +136,7 @@ HTML;
/**
* Fills form fields using the provided data.
*
* @param array $data
*/
public function fill(array $data){
@ -154,6 +155,7 @@ HTML;
/**
* Refills form fields using the provided data, given that the form ID matches.
*
* @param array $data
* @return string|bool Truthy if all fields were present, indicating that the form is ready for validation. The truthy value is the submit button value if present, or true if no button had a set value.
*/
@ -161,7 +163,7 @@ HTML;
if (!isset($data[self::ACTION_KEY]) || $data[self::ACTION_KEY] !== $this->id){
return false;
}
$this->is_filled = true;
$filled_fields = 0;
@ -180,7 +182,7 @@ HTML;
if ($filled_fields !== count($this->fields)){
return false;
}
if (isset($data[self::RELOADED_KEY])){
if (isset($data[self::MESSAGES_KEY])){
array_push($this->messages, ...$data[self::MESSAGES_KEY]);
@ -194,6 +196,7 @@ HTML;
/**
* Reloads the form, saving data and form messages in a session.
*
* @param array $data
* @return ReloadFormAction
*/
@ -248,7 +251,7 @@ HTML;
}
$element->echoBody();
/** @noinspection PhpUnusedLocalVariableInspection */
foreach($groups as $group){
echo '</div>';

View File

@ -28,7 +28,7 @@ class RequireTracker implements IControlHandler{
if ($url === null){
$page_model = new BasicRootPageModel($req);
$error_model = new ErrorModel($page_model, 'Tracker Error', 'Tracker is missing in the URL.');
return view(new ErrorPage($error_model->load()));
}

View File

@ -41,7 +41,7 @@ class RegisterController extends AbstractHandlerController{
if ($sess->isLoggedOn()){
return redirect([BASE_URL_ENC, $req->getBasePath()->encoded()]);
}
$model = new RegisterModel($req, $this->tracker);
$data = $req->getData();

View File

@ -23,18 +23,18 @@ class SettingsController extends AbstractHandlerController{
protected function finally(Request $req, Session $sess): IAction{
$model = new SettingsModel($req);
$data = $req->getData();
if (!empty($data)){
$form = $model->getForm();
$action = $form->accept($data);
if (($action === $model::ACTION_REMOVE_BACKUP && $model->removeBackupFile()) ||
($action === $model::ACTION_UPDATE_SETTINGS && $model->updateConfig($data))
){
return $form->reload($data);
}
}
return view(new SettingsPage($model->load()));
}
}

View File

@ -8,6 +8,7 @@ use Pages\Components\Navigation\NavigationComponent;
interface IModel{
/**
* Loads data into the model.
*
* @return $this
*/
public function load(): IModel;

View File

@ -30,7 +30,7 @@ class AccountModel extends BasicMixedPageModel{
$this->menu_links->addLink(Text::withIcon('Profile', 'user'), '/account');
$this->menu_links->addLink(Text::withIcon('Security', 'key'), '/account/security');
$this->menu_actions->addActionButton(Text::withIcon('Logout', 'switch'), self::ACTION_LOGOUT);
return $this;

View File

@ -43,7 +43,7 @@ class AccountSecurityModel extends AccountModel{
$form->addButton('submit', 'Change Password')
->icon('pencil');
$this->change_password_form = $form;
}

View File

@ -25,7 +25,7 @@ use Validation\Validator;
class TrackersModel extends BasicRootPageModel{
public const ACTION_CREATE = 'Create';
public const ACTION_DELETE = 'Delete';
public const PERM_LIST = 'trackers.list';
public const PERM_LIST_HIDDEN = 'trackers.list.hidden';
public const PERM_ADD = 'trackers.add';
@ -39,7 +39,7 @@ class TrackersModel extends BasicRootPageModel{
public function __construct(Request $req, Permissions $perms){
parent::__construct($req);
$this->perms = $perms;
$this->table = new TableComponent();
@ -130,11 +130,11 @@ class TrackersModel extends BasicRootPageModel{
$name = $data['Name'];
$url = $data['Url'];
$hidden = (bool)($data['Hidden'] ?? false);
$validator = new Validator();
$validator->str('Name', $name)->notEmpty();
$validator->str('Url', $url)->notEmpty()->notContains('/')->notContains('\\');
try{
$validator->validate();
$trackers = new TrackerTable(DB::get());
@ -156,12 +156,12 @@ class TrackersModel extends BasicRootPageModel{
return false;
}
}
$this->form->onGeneralError($e);
}catch(Exception $e){
$this->form->onGeneralError($e);
}
return false;
}

View File

@ -179,9 +179,17 @@ class UsersModel extends BasicRootPageModel{
return false;
}
$users = new UserTable(DB::get());
$users->deleteById((int)$data['User']);
return true;
try{
$users = new UserTable(DB::get());
$users->deleteById((int)$data['User']);
return true;
}catch(PDOException $e){
if ($e->getCode() === SQL::CONSTRAINT_VIOLATION){
// TODO show message with reason which foreign key checks failed, i.e. cannot delete tracker owner
}
throw $e;
}
}
}

View File

@ -45,10 +45,10 @@ class MembersModel extends BasicTrackerPageModel{
$this->table = new TableComponent();
$this->table->ifEmpty('No members found.');
$this->table->addColumn('Username');
$this->table->addColumn('Username')->bold();
$this->table->addColumn('Role');
if ($this->perms->checkTracker($tracker, self::PERM_MANAGE)){
if ($perms->checkTracker($tracker, self::PERM_MANAGE)){
$this->table->addColumn('Actions')->right()->tight();
$roles = (new TrackerPermTable(DB::get(), $tracker))->listRoles();

View File

@ -22,7 +22,7 @@ class AccountSecurityPage extends AccountPage{
<h3>Change Password</h3>
<article>
HTML;
$this->model->getChangePasswordForm()->echoBody();
echo <<<HTML

View File

@ -67,6 +67,8 @@ foreach(['&/', 'tracker/:tracker/&/'] as $base){
$router->add($base.'account/security', 'Mixed/AccountSecurityController');
}
// TODO CSRF
function handle_error(int $code, string $title, string $message, ?Request $req = null): void{
http_response_code($code);
$page_model = new BasicRootPageModel($req ?? new Request('', '', []));