1
0
mirror of https://github.com/chylex/Lightning-Tracker.git synced 2025-07-29 22:59:08 +02:00

Replace calls to Session::get inside models with constructor parameters

This commit is contained in:
chylex 2020-09-23 01:50:18 +02:00
parent f7ac6e168c
commit dac23cffd6
21 changed files with 87 additions and 89 deletions

View File

@ -3,13 +3,13 @@ declare(strict_types = 1);
namespace Database\Filters\Types;
use Data\UserId;
use Database\Filters\AbstractFilter;
use Database\Filters\Conditions\FieldLike;
use Database\Filters\Field;
use Database\Filters\General\Filtering;
use Database\Filters\General\Sorting;
use Database\Filters\IWhereCondition;
use Database\Objects\UserProfile;
use PDOStatement;
final class ProjectFilter extends AbstractFilter{
@ -19,19 +19,19 @@ final class ProjectFilter extends AbstractFilter{
' OR EXISTS(SELECT 1 FROM project_members pm WHERE pm.project_id = '.Field::sql('id', $table_name).' AND pm.user_id = :user_id_2)';
}
public static function bindUserVisibility(PDOStatement $stmt, UserProfile $user): void{
bind($stmt, 'user_id_1', $user->getId());
bind($stmt, 'user_id_2', $user->getId());
public static function bindUserVisibility(PDOStatement $stmt, UserId $user_id): void{
bind($stmt, 'user_id_1', $user_id);
bind($stmt, 'user_id_2', $user_id);
}
public static function empty(): self{
return new self();
}
private ?UserProfile $visible_to = null;
private ?UserId $visible_to = null;
private bool $visible_to_set = false;
public function visibleTo(?UserProfile $visible_to): self{
public function visibleTo(?UserId $visible_to): self{
$this->visible_to = $visible_to;
$this->visible_to_set = true;
return $this;
@ -42,9 +42,9 @@ final class ProjectFilter extends AbstractFilter{
if ($this->visible_to_set){
$conditions[] = new class($this->visible_to) implements IWhereCondition{
private ?UserProfile $visible_to;
private ?UserId $visible_to;
public function __construct(?UserProfile $visible_to){
public function __construct(?UserId $visible_to){
$this->visible_to = $visible_to;
}

View File

@ -7,6 +7,7 @@ use Data\IssuePriority;
use Data\IssueScale;
use Data\IssueStatus;
use Data\IssueType;
use Data\UserId;
use Pages\Components\Markup\LightMarkComponent;
use Session\Permissions\ProjectPermissions;
@ -64,26 +65,25 @@ final class IssueDetail extends IssueInfo{
return $this->assignee;
}
public function isAuthorOrAssignee(UserProfile $user): bool{
$user_id = $user->getId();
public function isAuthorOrAssignee(UserId $user_id): bool{
$author = $this->author;
$assignee = $this->assignee;
return ($author !== null && $user_id->equals($author->getId())) || ($assignee !== null && $user_id->equals($assignee->getId()));
}
public function isAssignee(UserProfile $user): bool{
return $this->assignee !== null && $user->getId()->equals($this->assignee->getId());
public function isAssignee(UserId $user_id): bool{
return $this->assignee !== null && $user_id->equals($this->assignee->getId());
}
public function getEditLevel(?UserProfile $user, ProjectPermissions $perms): int{
$can_edit = ($user !== null && $this->isAuthorOrAssignee($user)) || $perms->check(ProjectPermissions::EDIT_ALL_ISSUES);
public function getEditLevel(?UserId $user_id, ProjectPermissions $perms): int{
$can_edit = ($user_id !== null && $this->isAuthorOrAssignee($user_id)) || $perms->check(ProjectPermissions::EDIT_ALL_ISSUES);
if (!$can_edit){
return self::EDIT_FORBIDDEN;
}
$all_fields = ($user !== null && $this->isAssignee($user)) || $perms->check(ProjectPermissions::MODIFY_ALL_ISSUE_FIELDS);
$all_fields = ($user_id !== null && $this->isAssignee($user_id)) || $perms->check(ProjectPermissions::MODIFY_ALL_ISSUE_FIELDS);
return $all_fields ? self::EDIT_ALL_FIELDS : self::EDIT_BASIC_FIELDS;
}
}

View File

@ -121,13 +121,13 @@ final class ProjectTable extends AbstractTable{
return $this->fetchMap($stmt, fn($v): ProjectInfo => new ProjectInfo($v['id'], $v['name'], $v['url'], $user_id));
}
public function getInfoFromUrl(string $url, ?UserProfile $profile, SystemPermissions $perms): ?ProjectVisibilityInfo{
$user_visibility_clause = $profile === null ? '' : ProjectFilter::getUserVisibilityClause();
public function getInfoFromUrl(string $url, ?UserId $logon_user_id, SystemPermissions $perms): ?ProjectVisibilityInfo{
$user_visibility_clause = $logon_user_id === null ? '' : ProjectFilter::getUserVisibilityClause();
$stmt = $this->db->prepare('SELECT id, name, owner_id, (hidden = FALSE'.$user_visibility_clause.') AS visible FROM projects WHERE url = :url');
$stmt->bindValue('url', $url);
if ($profile !== null){
ProjectFilter::bindUserVisibility($stmt, $profile);
if ($logon_user_id !== null){
ProjectFilter::bindUserVisibility($stmt, $logon_user_id);
}
$stmt->execute();

View File

@ -3,22 +3,22 @@ declare(strict_types = 1);
namespace Database\Tables;
use Data\UserId;
use Database\AbstractProjectTable;
use Database\Objects\MilestoneProgress;
use Database\Objects\UserProfile;
final class ProjectUserSettingsTable extends AbstractProjectTable{
public function toggleActiveMilestone(UserProfile $user, int $milestone_id): void{
public function toggleActiveMilestone(UserId $user_id, int $milestone_id): void{
$sql = <<<SQL
INSERT INTO project_user_settings (project_id, user_id, active_milestone)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE active_milestone = IF(active_milestone = VALUES(active_milestone), NULL, VALUES(active_milestone))
SQL;
$this->execute($sql, 'ISI', [$this->getProjectId(), $user->getId(), $milestone_id]);
$this->execute($sql, 'ISI', [$this->getProjectId(), $user_id, $milestone_id]);
}
public function getActiveMilestoneProgress(UserProfile $user): ?MilestoneProgress{
public function getActiveMilestoneProgress(UserId $user_id): ?MilestoneProgress{
$sql = <<<SQL
SELECT m.milestone_id AS id,
m.title AS title,
@ -31,7 +31,7 @@ WHERE tus.user_id = ? AND tus.project_id = ?
GROUP BY m.milestone_id
SQL;
$stmt = $this->execute($sql, 'SI', [$user->getId(), $this->getProjectId()]);
$stmt = $this->execute($sql, 'SI', [$user_id, $this->getProjectId()]);
$res = $this->fetchOneRaw($stmt);
return $res === false ? null : new MilestoneProgress($res['id'], $res['title'], $res['percentage_done'] === null ? null : (int)$res['percentage_done']);
}

View File

@ -38,7 +38,7 @@ class LoadProject implements IControlHandler{
}
$projects = new ProjectTable(DB::get());
$info = $projects->getInfoFromUrl($url, $sess->getLogonUser(), $sess->getPermissions()->system());
$info = $projects->getInfoFromUrl($url, $sess->getLogonUserId(), $sess->getPermissions()->system());
if ($info === null || !$info->isVisible()){
return message($req, 'Project Error', 'Project was not found.');

View File

@ -27,7 +27,7 @@ class IssueDetailController extends AbstractProjectController{
protected function projectFinally(Request $req, Session $sess, ProjectInfo $project): IAction{
$action = $req->getAction();
$perms = $sess->getPermissions()->project($project);
$model = new IssueDetailModel($req, $project, $perms, $this->issue_id);
$model = new IssueDetailModel($req, $project, $perms, $sess->getLogonUserId(), $this->issue_id);
if ($action !== null){
if (!$model->canEditStatus()){

View File

@ -41,7 +41,7 @@ class IssueEditController extends AbstractProjectController{
$model = new IssueEditModel($req, $project, $perms, $logon_user, CreateOrEditIssue::edit($this->issue_id));
$issue = $model->getIssue();
if ($issue === null || $issue->getEditLevel($logon_user, $perms) === IssueDetail::EDIT_FORBIDDEN){
if ($issue === null || $issue->getEditLevel($logon_user->getId(), $perms) === IssueDetail::EDIT_FORBIDDEN){
return message($req, 'Permission Error', 'You do not have permission to edit this issue.', $project);
}
}

View File

@ -20,7 +20,7 @@ class IssuesController extends AbstractProjectController{
}
protected function projectFinally(Request $req, Session $sess, ProjectInfo $project): IAction{
return view(new IssuesPage((new IssuesModel($req, $project, $sess->getPermissions()->project($project)))->load()));
return view(new IssuesPage((new IssuesModel($req, $project, $sess->getPermissions()->project($project), $sess->getLogonUserId()))->load()));
}
}

View File

@ -26,7 +26,7 @@ class MembersController extends AbstractProjectController{
protected function projectFinally(Request $req, Session $sess, ProjectInfo $project): IAction{
$action = $req->getAction();
$perms = $sess->getPermissions()->project($project);
$model = new MembersModel($req, $project, $perms);
$model = new MembersModel($req, $project, $perms, $sess->getLogonUserId());
if ($action === $model::ACTION_INVITE && $perms->require(ProjectPermissions::MANAGE_MEMBERS) && $model->inviteUser($req->getData())){
return reload();

View File

@ -18,7 +18,7 @@ class MilestonesController extends AbstractProjectController{
protected function projectFinally(Request $req, Session $sess, ProjectInfo $project): IAction{
$action = $req->getAction();
$perms = $sess->getPermissions()->project($project);
$model = new MilestonesModel($req, $project, $perms);
$model = new MilestonesModel($req, $project, $perms, $sess->getLogonUserId());
if ($action !== null){
$data = $req->getData();

View File

@ -24,7 +24,7 @@ class ProjectsController extends AbstractHandlerController{
protected function finally(Request $req, Session $sess): IAction{
$perms = $sess->getPermissions()->system();
$model = new ProjectModel($req, $perms);
$model = new ProjectModel($req, $perms, $sess->getLogonUserId());
if ($req->getAction() === $model::ACTION_CREATE){
$logon_user = $sess->getLogonUser();

View File

@ -26,7 +26,7 @@ class UsersController extends AbstractHandlerController{
protected function finally(Request $req, Session $sess): IAction{
$perms = $sess->getPermissions()->system();
$model = new UsersModel($req, $perms);
$model = new UsersModel($req, $perms, $sess->getLogonUserId());
if ($req->getAction() === $model::ACTION_CREATE && $perms->require(SystemPermissions::CREATE_USER) && $model->createUser($req->getData())){
return reload();

View File

@ -66,15 +66,15 @@ class BasicProjectPageModel extends AbstractPageModel{
}
$this->loaded_active_milestone = true;
$logon_user = Session::get()->getLogonUser();
$logon_user_id = Session::get()->getLogonUserId();
if ($logon_user === null){
if ($logon_user_id === null){
$milestone = null;
}
else{
try{
$settings = new ProjectUserSettingsTable(DB::get(), $this->getProject());
$milestone = $settings->getActiveMilestoneProgress($logon_user);
$milestone = $settings->getActiveMilestoneProgress($logon_user_id);
}catch(Exception $e){
Log::critical($e);
$milestone = null;

View File

@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace Pages\Models\Project;
use Data\IssueStatus;
use Data\UserId;
use Database\DB;
use Database\Objects\IssueDetail;
use Database\Objects\ProjectInfo;
@ -14,7 +15,6 @@ use Pages\Components\Text;
use Pages\Models\BasicProjectPageModel;
use Routing\Request;
use Session\Permissions\ProjectPermissions;
use Session\Session;
class IssueDetailModel extends BasicProjectPageModel{
public const ACTION_UPDATE_TASKS = 'Update';
@ -29,7 +29,7 @@ class IssueDetailModel extends BasicProjectPageModel{
private ?IssueDetail $issue;
private int $edit_level;
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms, int $issue_id){
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms, UserId $logon_user_id, int $issue_id){
parent::__construct($req, $project);
$this->perms = $perms;
$this->issue_id = $issue_id;
@ -41,7 +41,7 @@ class IssueDetailModel extends BasicProjectPageModel{
$this->edit_level = IssueDetail::EDIT_FORBIDDEN;
}
else{
$this->edit_level = $this->issue->getEditLevel(Session::get()->getLogonUser(), $perms);
$this->edit_level = $this->issue->getEditLevel($logon_user_id, $perms);
}
}

View File

@ -85,7 +85,7 @@ class IssueEditModel extends BasicProjectPageModel{
else{
$this->issue_id = $edit_request->getIssueId();
$this->issue = (new IssueTable(DB::get(), $project))->getIssueDetail($this->issue_id);
$this->edit_level = $this->issue === null ? IssueDetail::EDIT_FORBIDDEN : $this->issue->getEditLevel($editor, $perms);
$this->edit_level = $this->issue === null ? IssueDetail::EDIT_FORBIDDEN : $this->issue->getEditLevel($editor->getId(), $perms);
}
}

View File

@ -7,6 +7,7 @@ use Data\IssuePriority;
use Data\IssueScale;
use Data\IssueStatus;
use Data\IssueType;
use Data\UserId;
use Database\DB;
use Database\Filters\Types\IssueFilter;
use Database\Objects\IssueInfo;
@ -22,7 +23,6 @@ use Pages\Components\Text;
use Pages\Models\BasicProjectPageModel;
use Routing\Request;
use Session\Permissions\ProjectPermissions;
use Session\Session;
class IssuesModel extends BasicProjectPageModel{
/**
@ -36,10 +36,12 @@ class IssuesModel extends BasicProjectPageModel{
}
private ProjectPermissions $perms;
private UserId $logon_user_id;
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms){
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms, UserId $logon_user_id){
parent::__construct($req, $project);
$this->perms = $perms;
$this->logon_user_id = $logon_user_id;
}
public function createMenuAction(): ?SidemenuComponent{
@ -87,11 +89,9 @@ class IssuesModel extends BasicProjectPageModel{
$filtering_assignee = $header->addMultiSelect('assignee')->label('Assignee');
$filtering_assignee->addOption('', Text::missing('Nobody'));
$logon_user_id = Session::get()->getLogonUserId();
if ($logon_user_id !== null){
$filtering_author->addOption($logon_user_id->raw(), Text::missing('You'));
$filtering_assignee->addOption($logon_user_id->raw(), Text::missing('You'));
if ($this->logon_user_id !== null){
$filtering_author->addOption($this->logon_user_id->raw(), Text::missing('You'));
$filtering_assignee->addOption($this->logon_user_id->raw(), Text::missing('You'));
$groups = [
[$filtering_author, $issues->listAuthors()],
@ -102,7 +102,7 @@ class IssuesModel extends BasicProjectPageModel{
foreach($users as $user){
$user_id = $user->getId();
if (!$user_id->equals($logon_user_id)){
if (!$user_id->equals($this->logon_user_id)){
$select->addOption($user_id->raw(), Text::plain($user->getName()));
}
}

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace Pages\Models\Project;
use Data\UserId;
use Database\DB;
use Database\Filters\Types\ProjectMemberFilter;
use Database\Objects\ProjectInfo;
@ -17,12 +18,12 @@ use Pages\Components\Text;
use Pages\Models\BasicProjectPageModel;
use Routing\Request;
use Session\Permissions\ProjectPermissions;
use Session\Session;
class MembersModel extends BasicProjectPageModel{
public const ACTION_INVITE = 'Invite';
private ProjectPermissions $perms;
private ?UserId $logon_user_id;
private FormComponent $invite_form;
@ -31,17 +32,14 @@ class MembersModel extends BasicProjectPageModel{
*/
private array $editable_roles = [];
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms){
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms, ?UserId $logon_user_id){
parent::__construct($req, $project);
$this->perms = $perms;
$this->logon_user_id = $logon_user_id;
if ($perms->check(ProjectPermissions::MANAGE_MEMBERS)){
$logon_user_id = Session::get()->getLogonUserId();
if ($logon_user_id !== null){
foreach((new ProjectRoleTable(DB::get(), $project))->listRolesAssignableBy($logon_user_id) as $role){
$this->editable_roles[$role->getId()] = $role->getTitle();
}
if ($perms->check(ProjectPermissions::MANAGE_MEMBERS) && $logon_user_id !== null){
foreach((new ProjectRoleTable(DB::get(), $project))->listRolesAssignableBy($logon_user_id) as $role){
$this->editable_roles[$role->getId()] = $role->getTitle();
}
}
}
@ -55,7 +53,7 @@ class MembersModel extends BasicProjectPageModel{
return (
$this->perms->check(ProjectPermissions::MANAGE_MEMBERS) &&
!$user_id->equals(Session::get()->getLogonUserId()) &&
!$user_id->equals($this->logon_user_id) &&
!$user_id->equals($this->getProject()->getOwnerId()) &&
($member->getRoleId() === null || array_key_exists($member->getRoleId(), $this->editable_roles))
);
@ -96,7 +94,7 @@ class MembersModel extends BasicProjectPageModel{
}
public function getInviteForm(): ?FormComponent{
if (!$this->perms->check(ProjectPermissions::MANAGE_MEMBERS)){
if ($this->logon_user_id === null || !$this->perms->check(ProjectPermissions::MANAGE_MEMBERS)){
return null;
}
@ -164,7 +162,7 @@ class MembersModel extends BasicProjectPageModel{
return false;
}
if ($role_id !== null && !(new ProjectRoleTable($db, $project))->isRoleAssignableBy($role_id, Session::get()->getLogonUserIdOrThrow())){
if ($role_id !== null && !(new ProjectRoleTable($db, $project))->isRoleAssignableBy($role_id, $this->logon_user_id)){
$form->invalidateField('Role', 'Invalid role.');
return false;
}

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace Pages\Models\Project;
use Data\UserId;
use Database\DB;
use Database\Filters\Types\MilestoneFilter;
use Database\Objects\MilestoneInfo;
@ -17,7 +18,6 @@ use Pages\Components\Table\TableComponent;
use Pages\Models\BasicProjectPageModel;
use Routing\Request;
use Session\Permissions\ProjectPermissions;
use Session\Session;
use Validation\FormValidator;
use Validation\ValidationException;
@ -30,12 +30,14 @@ class MilestonesModel extends BasicProjectPageModel{
private const BUTTON_MOVE_DOWN = 'Down';
private ProjectPermissions $perms;
private ?UserId $logon_user_id;
private FormComponent $create_form;
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms){
public function __construct(Request $req, ProjectInfo $project, ProjectPermissions $perms, ?UserId $logon_user_id){
parent::__construct($req, $project);
$this->perms = $perms;
$this->logon_user_id = $logon_user_id;
}
public function canManageMilestones(): bool{
@ -167,18 +169,12 @@ class MilestonesModel extends BasicProjectPageModel{
public function toggleActiveMilestone(array $data): bool{
$milestone = get_int($data, 'Milestone');
if ($milestone === null){
return false;
}
$logon_user = Session::get()->getLogonUser();
if ($logon_user === null){
if ($milestone === null || $this->logon_user_id === null){
return false;
}
$settings = new ProjectUserSettingsTable(DB::get(), $this->getProject());
$settings->toggleActiveMilestone($logon_user, (int)$data['Milestone']);
$settings->toggleActiveMilestone($this->logon_user_id, (int)$data['Milestone']);
return true;
}
}

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace Pages\Models\Root;
use Data\UserId;
use Database\DB;
use Database\Filters\General\Pagination;
use Database\Filters\Types\ProjectFilter;
@ -16,7 +17,6 @@ use Pages\Components\Table\TableComponent;
use Pages\Models\BasicRootPageModel;
use Routing\Request;
use Session\Permissions\SystemPermissions;
use Session\Session;
use Validation\FormValidator;
use Validation\ValidationException;
@ -24,12 +24,14 @@ class ProjectModel extends BasicRootPageModel{
public const ACTION_CREATE = 'Create';
private SystemPermissions $perms;
private ?UserId $logon_user_id;
private FormComponent $create_form;
public function __construct(Request $req, SystemPermissions $perms){
public function __construct(Request $req, SystemPermissions $perms, ?UserId $logon_user_id){
parent::__construct($req);
$this->perms = $perms;
$this->logon_user_id = $logon_user_id;
}
public function canViewPubliclyVisibleProjects(): bool{
@ -51,7 +53,7 @@ class ProjectModel extends BasicRootPageModel{
}
if (!$this->perms->check(SystemPermissions::LIST_ALL_PROJECTS)){
$filter = $filter->visibleTo(Session::get()->getLogonUser());
$filter = $filter->visibleTo($this->logon_user_id);
}
$projects = new ProjectTable(DB::get());

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace Pages\Models\Root;
use Data\UserId;
use Database\DB;
use Database\Filters\Types\UserFilter;
use Database\Objects\UserInfo;
@ -17,7 +18,6 @@ use Pages\Models\BasicRootPageModel;
use Pages\Models\Mixed\RegisterModel;
use Routing\Request;
use Session\Permissions\SystemPermissions;
use Session\Session;
use Validation\FormValidator;
use Validation\ValidationException;
@ -25,6 +25,7 @@ class UsersModel extends BasicRootPageModel{
public const ACTION_CREATE = 'Create';
private SystemPermissions $perms;
private ?UserId $logon_user_id;
private FormComponent $create_form;
@ -33,17 +34,14 @@ class UsersModel extends BasicRootPageModel{
*/
private array $editable_roles = [];
public function __construct(Request $req, SystemPermissions $perms){
public function __construct(Request $req, SystemPermissions $perms, ?UserId $logon_user_id){
parent::__construct($req);
$this->perms = $perms;
$this->logon_user_id = $logon_user_id;
if ($perms->check(SystemPermissions::MANAGE_USERS)){
$logon_user_id = Session::get()->getLogonUserId();
if ($logon_user_id !== null){
foreach((new SystemRoleTable(DB::get()))->listRolesAssignableBy($logon_user_id) as $role){
$this->editable_roles[$role->getId()] = $role->getTitle();
}
if ($perms->check(SystemPermissions::MANAGE_USERS) && $logon_user_id !== null){
foreach((new SystemRoleTable(DB::get()))->listRolesAssignableBy($logon_user_id) as $role){
$this->editable_roles[$role->getId()] = $role->getTitle();
}
}
}
@ -59,7 +57,7 @@ class UsersModel extends BasicRootPageModel{
public function canEditUser(UserInfo $user): bool{
return (
$this->canManageUsers() &&
!$user->getId()->equals(Session::get()->getLogonUserId()) &&
!$user->getId()->equals($this->logon_user_id) &&
($user->getRoleId() === null || array_key_exists($user->getRoleId(), $this->editable_roles))
);
}

View File

@ -84,19 +84,23 @@ final class Session{
return $this->getLogin()->getLogonUser();
}
public function getLogonUserId(): ?UserId{
$logon_user = $this->getLogonUser();
return $logon_user === null ? null : $logon_user->getId();
}
public function getLogonUserIdOrThrow(): UserId{
public function getLogonUserOrThrow(): ?UserProfile{
$logon_user = $this->getLogonUser();
if ($logon_user === null){
throw new LogicException('Expected a logged in user.');
}
return $logon_user->getId();
return $logon_user;
}
public function getLogonUserId(): ?UserId{
$logon_user = $this->getLogonUser();
return $logon_user === null ? null : $logon_user->getId();
}
public function getLogonUserIdOrThrow(): UserId{
return $this->getLogonUserOrThrow()->getId();
}
public function getPermissions(): PermissionManager{