mirror of
https://github.com/chylex/Lightning-Tracker.git
synced 2025-04-10 02:15:43 +02:00
Add tracker member edit page
This commit is contained in:
parent
39d5d0d7f6
commit
a3961f7560
src
@ -62,6 +62,24 @@ SQL;
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function setRole(int $user_id, ?int $role_id){
|
||||
$stmt = $this->db->prepare('UPDATE tracker_members SET role_id = ? WHERE user_id = ? AND tracker_id = ?');
|
||||
$stmt->bindValue(1, $role_id, $role_id === null ? PDO::PARAM_NULL : PDO::PARAM_INT);
|
||||
$stmt->bindValue(2, $user_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(3, $this->getTrackerId(), PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
public function getRoleIdStr(int $user_id): ?string{
|
||||
$stmt = $this->db->prepare('SELECT role_id 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();
|
||||
|
||||
$res = $this->fetchOneColumn($stmt);
|
||||
return $res === false ? null : ($res === null ? '' : strval((int)$res));
|
||||
}
|
||||
|
||||
public function checkMembershipExists(int $user_id): bool{
|
||||
$stmt = $this->db->prepare('SELECT 1 FROM tracker_members WHERE user_id = ? AND tracker_id = ?');
|
||||
$stmt->bindValue(1, $user_id, PDO::PARAM_INT);
|
||||
|
54
src/Pages/Controllers/Tracker/MemberEditController.php
Normal file
54
src/Pages/Controllers/Tracker/MemberEditController.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pages\Controllers\Tracker;
|
||||
|
||||
use Database\Objects\TrackerInfo;
|
||||
use Generator;
|
||||
use Pages\Controllers\AbstractTrackerController;
|
||||
use Pages\Controllers\Handlers\LoadStringId;
|
||||
use Pages\Controllers\Handlers\RequireLoginState;
|
||||
use Pages\Controllers\Handlers\RequireTrackerPermission;
|
||||
use Pages\IAction;
|
||||
use Pages\Models\BasicRootPageModel;
|
||||
use Pages\Models\BasicTrackerPageModel;
|
||||
use Pages\Models\ErrorModel;
|
||||
use Pages\Models\Tracker\MemberEditModel;
|
||||
use Pages\Models\Tracker\MembersModel;
|
||||
use Pages\Views\ErrorPage;
|
||||
use Pages\Views\Tracker\MemberEditPage;
|
||||
use Routing\Link;
|
||||
use Routing\Request;
|
||||
use Session\Session;
|
||||
use function Pages\Actions\redirect;
|
||||
use function Pages\Actions\view;
|
||||
|
||||
class MemberEditController extends AbstractTrackerController{
|
||||
private ?string $member_name;
|
||||
|
||||
protected function trackerHandlers(TrackerInfo $tracker): Generator{
|
||||
yield new RequireLoginState(true);
|
||||
yield new RequireTrackerPermission($tracker, MembersModel::PERM_LIST);
|
||||
yield new RequireTrackerPermission($tracker, MembersModel::PERM_MANAGE);
|
||||
yield new LoadStringId($this->member_name, 'member', $tracker);
|
||||
}
|
||||
|
||||
protected function runTracker(Request $req, Session $sess, TrackerInfo $tracker): IAction{
|
||||
$model = new MemberEditModel($req, $tracker, $this->member_name);
|
||||
|
||||
if (!$model->canEdit()){
|
||||
$page_model = new BasicTrackerPageModel($req, $tracker);
|
||||
$error_model = new ErrorModel($page_model, 'Permission Error', 'You are not allowed to edit this member.');
|
||||
|
||||
return view(new ErrorPage($error_model->load()));
|
||||
}
|
||||
|
||||
if ($req->getAction() === $model::ACTION_EDIT && $model->editMember($req->getData())){
|
||||
return redirect(Link::fromBase($req, 'members'));
|
||||
}
|
||||
|
||||
return view(new MemberEditPage($model->load()));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
121
src/Pages/Models/Tracker/MemberEditModel.php
Normal file
121
src/Pages/Models/Tracker/MemberEditModel.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pages\Models\Tracker;
|
||||
|
||||
use Database\DB;
|
||||
use Database\Objects\TrackerInfo;
|
||||
use Database\Tables\TrackerMemberTable;
|
||||
use Database\Tables\TrackerPermTable;
|
||||
use Database\Tables\UserTable;
|
||||
use Exception;
|
||||
use Pages\Components\Forms\FormComponent;
|
||||
use Pages\IModel;
|
||||
use Pages\Models\BasicTrackerPageModel;
|
||||
use Routing\Request;
|
||||
use Session\Session;
|
||||
use Validation\FormValidator;
|
||||
use Validation\ValidationException;
|
||||
use function Database\protect;
|
||||
|
||||
class MemberEditModel extends BasicTrackerPageModel{
|
||||
public const ACTION_EDIT = 'Edit';
|
||||
|
||||
private string $member_name;
|
||||
private ?int $user_id;
|
||||
private bool $can_edit;
|
||||
private bool $has_member = false;
|
||||
|
||||
private FormComponent $form;
|
||||
|
||||
public function __construct(Request $req, TrackerInfo $tracker, string $member_name){
|
||||
parent::__construct($req, $tracker);
|
||||
$this->member_name = $member_name;
|
||||
|
||||
$logon_user = Session::get()->getLogonUser();
|
||||
$logon_user_id = $logon_user === null ? null : $logon_user->getId();
|
||||
|
||||
$users = new UserTable(DB::get());
|
||||
$this->user_id = $users->findIdByName($member_name);
|
||||
$this->can_edit = !($this->user_id === $logon_user_id || $this->user_id === $tracker->getOwnerId());
|
||||
|
||||
$this->form = new FormComponent(self::ACTION_EDIT);
|
||||
|
||||
$select_role = $this->form->addSelect('Role')
|
||||
->dropdown()
|
||||
->addOption('', '(Default)');
|
||||
|
||||
foreach((new TrackerPermTable(DB::get(), $tracker))->listRoles() as $role){
|
||||
if (!$role->isSpecial()){
|
||||
$select_role->addOption(strval($role->getId()), $role->getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
$this->form->addButton('submit', 'Edit Member')->icon('pencil');
|
||||
}
|
||||
|
||||
public function load(): IModel{
|
||||
parent::load();
|
||||
|
||||
if (!$this->form->isFilled() && $this->user_id !== null){
|
||||
$members = new TrackerMemberTable(DB::get(), $this->getTracker());
|
||||
$role = $members->getRoleIdStr($this->user_id);
|
||||
|
||||
if ($role !== null){
|
||||
$this->has_member = true;
|
||||
$this->form->fill(['Role' => $role]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function canEdit(): bool{
|
||||
return $this->can_edit;
|
||||
}
|
||||
|
||||
public function hasMember(): bool{
|
||||
return $this->has_member;
|
||||
}
|
||||
|
||||
public function getMemberNameSafe(): string{
|
||||
return protect($this->member_name);
|
||||
}
|
||||
|
||||
public function getEditForm(): FormComponent{
|
||||
return $this->form;
|
||||
}
|
||||
|
||||
public function editMember(array $data): bool{
|
||||
if (!$this->form->accept($data)){
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = DB::get();
|
||||
$tracker = $this->getTracker();
|
||||
|
||||
$validator = new FormValidator($data);
|
||||
$role = empty($data['Role']) ? null : (int)$data['Role'];
|
||||
|
||||
try{
|
||||
$validator->validate();
|
||||
|
||||
if ($role !== null && (new TrackerPermTable($db, $tracker))->isRoleSpecial($role)){
|
||||
$this->form->invalidateField('Role', 'Invalid role.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$members = new TrackerMemberTable($db, $tracker);
|
||||
$members->setRole($this->user_id, $role);
|
||||
return true;
|
||||
}catch(ValidationException $e){
|
||||
$this->form->invalidateFields($e->getFields());
|
||||
}catch(Exception $e){
|
||||
$this->form->onGeneralError($e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -17,6 +17,7 @@ use Pages\Components\Text;
|
||||
use Pages\IModel;
|
||||
use Pages\Models\BasicTrackerPageModel;
|
||||
use PDOException;
|
||||
use Routing\Link;
|
||||
use Routing\Request;
|
||||
use Session\Permissions;
|
||||
use Session\Session;
|
||||
@ -31,7 +32,6 @@ class MembersModel extends BasicTrackerPageModel{
|
||||
private Permissions $perms;
|
||||
private TableComponent $table;
|
||||
private ?FormComponent $form;
|
||||
// TODO add a way to edit an existing member
|
||||
|
||||
public function __construct(Request $req, TrackerInfo $tracker, Permissions $perms){
|
||||
parent::__construct($req, $tracker);
|
||||
@ -95,13 +95,16 @@ class MembersModel extends BasicTrackerPageModel{
|
||||
$sorting = $filter->sort($this->getReq());
|
||||
|
||||
foreach($members->listMembers($filter) as $member){
|
||||
$row = [$member->getUserNameSafe(),
|
||||
$name_safe = $member->getUserNameSafe();
|
||||
|
||||
$row = [$name_safe,
|
||||
$member->getRoleTitleSafe() ?? Text::missing('Default')];
|
||||
|
||||
$user_id = $member->getUserId();
|
||||
$is_self_or_owner = $user_id === $logon_user_id || $user_id === $owner_id;
|
||||
|
||||
if ($this->perms->checkTracker($tracker, self::PERM_MANAGE)){
|
||||
$user_id = $member->getUserId();
|
||||
|
||||
if ($user_id === $logon_user_id || $user_id === $owner_id){
|
||||
if ($is_self_or_owner){
|
||||
$row[] = '';
|
||||
}
|
||||
else{
|
||||
@ -113,7 +116,11 @@ class MembersModel extends BasicTrackerPageModel{
|
||||
}
|
||||
}
|
||||
|
||||
$this->table->addRow($row);
|
||||
$row = $this->table->addRow($row);
|
||||
|
||||
if ($this->perms->checkTracker($tracker, self::PERM_MANAGE) && !$is_self_or_owner){
|
||||
$row->link(Link::fromBase($this->getReq(), 'members', $name_safe));
|
||||
}
|
||||
}
|
||||
|
||||
$this->table->setupColumnSorting($sorting);
|
||||
|
47
src/Pages/Views/Tracker/MemberEditPage.php
Normal file
47
src/Pages/Views/Tracker/MemberEditPage.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pages\Views\Tracker;
|
||||
|
||||
use Pages\Components\Forms\FormComponent;
|
||||
use Pages\Models\Tracker\MemberEditModel;
|
||||
use Pages\Views\AbstractTrackerPage;
|
||||
|
||||
class MemberEditPage extends AbstractTrackerPage{
|
||||
private MemberEditModel $model;
|
||||
|
||||
public function __construct(MemberEditModel $model){
|
||||
parent::__construct($model);
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
protected function getSubtitle(): string{
|
||||
return 'Members';
|
||||
}
|
||||
|
||||
protected function getHeading(): string{
|
||||
$name = $this->model->hasMember() ? ' - '.$this->model->getMemberNameSafe() : '';
|
||||
return self::breadcrumb($this->model->getReq(), 'members').'Edit Member'.$name;
|
||||
}
|
||||
|
||||
protected function getLayout(): string{
|
||||
return self::LAYOUT_COMPACT;
|
||||
}
|
||||
|
||||
protected function echoPageHead(): void{
|
||||
FormComponent::echoHead();
|
||||
}
|
||||
|
||||
protected function echoPageBody(): void{
|
||||
if ($this->model->hasMember()){
|
||||
echo '<div class="max-width-400">';
|
||||
$this->model->getEditForm()->echoBody();
|
||||
echo '</div>';
|
||||
}
|
||||
else{
|
||||
echo '<p>Member not found.</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -100,6 +100,7 @@ $router->add('tracker/:tracker/&/milestones', 'Tracker/MilestonesController');
|
||||
$router->add('tracker/:tracker/&/milestones/:id', 'Tracker/MilestoneEditController');
|
||||
$router->add('tracker/:tracker/&/milestones/:id/delete', 'Tracker/MilestoneDeleteController');
|
||||
$router->add('tracker/:tracker/&/members', 'Tracker/MembersController');
|
||||
$router->add('tracker/:tracker/&/members/:id', 'Tracker/MemberEditController');
|
||||
$router->add('tracker/:tracker/&/settings', 'Tracker/SettingsController');
|
||||
$router->add('tracker/:tracker/&/delete', 'Root/TrackerDeleteController');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user