Commit 02cefcb6 authored by Jacob Priddy's avatar Jacob Priddy 👌
Browse files

Add route for users to be able to see what doors they are in

parent 6875e02b
......@@ -10,8 +10,10 @@ use Source\Authorization\Authorizer;
use Source\Exceptions\AuthenticationException;
use Source\UseCases\Users\GetUser\GetUserUseCase;
use Source\UseCases\Users\UpdateUser\UpdateUserUseCase;
use Source\UseCases\DoorUser\UserDoorAccess\MePresenter as DoorUserMePresenter;
use Source\UseCases\GroupUser\GetUserGroups\GetUserGroupsUseCase;
use Source\UseCases\TokenUser\GetUserTokens\GetUserTokensUseCase;
use Source\UseCases\DoorUser\UserDoorAccess\UserDoorAccessUseCase;
use Source\UseCases\Users\GetUser\APIPresenter as GetUserAPIPresenter;
use Source\UseCases\Users\UpdateUser\APIPresenter as UpdateUserAPIPresenter;
use Source\UseCases\GroupUser\GetUserGroups\APIPresenter as GetUserGroupsAPIPresenter;
......@@ -119,4 +121,18 @@ class MeController extends ApiController
{
return $this->respondWithData(['permissions' => $this->authorizer->getPermissions()]);
}
/**
* @param \Source\UseCases\DoorUser\UserDoorAccess\UserDoorAccessUseCase $userDoorAccessUseCase
* @return \Illuminate\Http\JsonResponse
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function doors(UserDoorAccessUseCase $userDoorAccessUseCase): JsonResponse
{
$presenter = new DoorUserMePresenter();
$userDoorAccessUseCase->getUserDoorRelationships($this->userId, $presenter);
return $this->respondWithData($presenter->getViewModel());
}
}
......@@ -50,6 +50,7 @@ use Source\UseCases\DoorGroup\GetGroupDoors\GetGroupDoorsUseCaseServiceProvider;
use Source\UseCases\GroupUser\GetGroupUsers\GetGroupUsersUseCaseServiceProvider;
use Source\UseCases\GroupUser\GetUserGroups\GetUserGroupsUseCaseServiceProvider;
use Source\UseCases\TokenUser\GetUserTokens\GetUserTokensUseCaseServiceProvider;
use Source\UseCases\DoorUser\UserDoorAccess\UserDoorAccessUseCaseServiceProvider;
use Source\UseCases\DoorGroup\AddDoorToGroup\AddDoorToGroupUseCaseServiceProvider;
use Source\UseCases\GroupUser\AddUserToGroup\AddUserToGroupUseCaseServiceProvider;
use Source\UseCases\Overrides\OverrideCreate\OverrideCreateUseCaseServiceProvider;
......@@ -107,6 +108,9 @@ class AppServiceProvider extends ServiceProvider
CreateUserUseCaseServiceProvider::class,
GetAllUsersUseCaseServiceProvider::class,
// DoorUser
UserDoorAccessUseCaseServiceProvider::class,
// Groups
GetGroupUseCaseServiceProvider::class,
CreateGroupUseCaseServiceProvider::class,
......
......@@ -131,5 +131,6 @@ Route::group(['middleware' => 'auth:api'], static function () {
Route::get('tokens', [MeController::class, 'tokens']);
Route::patch('/', [MeController::class, 'update']);
Route::get('permissions', [MeController::class, 'permissions']);
Route::get('/doors', [MeController::class, 'doors']);
});
});
......@@ -3,8 +3,10 @@
namespace Source\Gateways\DoorUser;
use Source\Entities\Door;
use Source\Entities\Group;
use Source\Sanitize\CastsTo;
use Source\Entities\HashedSearchable;
use Illuminate\Database\ConnectionInterface;
class DatabaseDoorUserRepository implements DoorUserRepository
......@@ -29,13 +31,13 @@ class DatabaseDoorUserRepository implements DoorUserRepository
$query = <<<QUERY
SELECT A.id, A.title, A.description, A.created_at, A.updated_at
FROM groups AS A
INNER JOIN door_group AS B ON B.group_id = A.id AND B.door_id = :door_id
INNER JOIN group_user AS C ON C.group_id = A.id AND C.user_id = :user_id
INNER JOIN door_group AS B ON B.group_id = A.id AND B.door_id = :DOOR_ID
INNER JOIN group_user AS C ON C.group_id = A.id AND C.user_id = :USER_ID
QUERY;
$commonGroups = $this->db->select($query, [
$doorId,
$userId
':DOOR_ID' => $doorId,
':USER_ID' => $userId,
]);
return array_map(function ($group) {
......
......@@ -3,6 +3,7 @@
namespace Source\Gateways\DoorUser;
use Source\Entities\Door;
use Source\Entities\Group;
class InMemoryDoorUserRepository implements DoorUserRepository
......
<?php
namespace Source\UseCases\DoorUser\UserDoorAccess;
use Source\Entities\Door;
use Source\Entities\Group;
use Source\Entities\Schedule;
use Source\UseCases\BasePresenter;
class MePresenter extends BasePresenter implements Presenter
{
protected array $viewModel = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$groups = $responseModel->getGroups();
$this->viewModel['groups'] = array_map(static function (Group $group) {
return [
'id' => $group->getId(),
'title' => $group->getTitle(),
'description' => $group->getDescription(),
];
}, $groups);
$this->viewModel['doors'] = [];
$this->viewModel['schedules'] = [];
foreach ($groups as $group) {
$this->viewModel['doors'][$group->getId()] = array_map(static function (Door $door) {
return [
'id' => $door->getId(),
'name' => $door->getName(),
'location' => $door->getLocation(),
];
}, $responseModel->getDoorsForGroup($group));
$this->viewModel['schedules'][$group->getId()] = array_map(static function (Schedule $schedule) {
return [
'id' => $schedule->getId(),
'description' => $schedule->getDescription(),
'rset' => $schedule->getRset(),
'duration' => $schedule->getDuration(),
];
}, $responseModel->getSchedulesForGroup($group));
}
}
/** @inheritDoc */
public function getViewModel(): array
{
return $this->viewModel;
}
}
<?php
namespace Source\UseCases\DoorUser\UserDoorAccess;
interface Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public function present(ResponseModel $responseModel): void;
/**
* @return array
*/
public function getViewModel(): array;
}
<?php
namespace Source\UseCases\DoorUser\UserDoorAccess;
use Source\Entities\Door;
use Source\Entities\Group;
use Source\Entities\Schedule;
class ResponseModel
{
/**
* @var \Source\Entities\Door[]
*/
protected array $groupDoorMap = [];
/**
* @var \Source\Entities\Schedule[]
*/
protected array $groupScheduleMap = [];
/**
* @var \Source\Entities\Group[]
*/
protected array $groups = [];
/**
* @param \Source\Entities\Group $group
*/
public function addGroup(Group $group): void
{
$this->groups[] = $group;
}
/**
* @param string $groupId
* @param \Source\Entities\Door $door
*/
public function addDoorToGroup(string $groupId, Door $door): void
{
if (isset($this->groupDoorMap[$groupId])) {
$this->groupDoorMap[$groupId][] = $door;
} else {
$this->groupDoorMap[$groupId] = [$door];
}
}
/**
* @param string $groupId
* @param \Source\Entities\Schedule $schedule
*/
public function addScheduleToGroup(string $groupId, Schedule $schedule): void
{
if (isset($this->groupScheduleMap[$groupId])) {
$this->groupScheduleMap[$groupId][] = $schedule;
} else {
$this->groupScheduleMap[$groupId] = [$schedule];
}
}
/**
* @return \Source\Entities\Group[]
*/
public function getGroups(): array
{
return $this->groups;
}
/**
* @param \Source\Entities\Group $group
* @return \Source\Entities\Door[]
*/
public function getDoorsForGroup(Group $group): array
{
return $this->groupDoorMap[$group->getId()] ?? [];
}
/**
* @param \Source\Entities\Group $group
* @return \Source\Entities\Schedule[]
*/
public function getSchedulesForGroup(Group $group): array
{
return $this->groupScheduleMap[$group->getId()] ?? [];
}
}
<?php
namespace Source\UseCases\DoorUser\UserDoorAccess;
use Source\Entities\Schedule;
use Source\Gateways\DoorGroup\DoorGroupRepository;
use Source\Gateways\Schedules\SchedulesRepository;
use Source\Gateways\GroupUser\GroupUserRepository;
class UserDoorAccess implements UserDoorAccessUseCase
{
/**
* @var \Source\Gateways\DoorGroup\DoorGroupRepository
*/
protected DoorGroupRepository $doorGroupRepository;
/**
* @var \Source\Gateways\Schedules\SchedulesRepository
*/
protected SchedulesRepository $schedulesRepository;
/**
* @var \Source\Gateways\GroupUser\GroupUserRepository
*/
protected GroupUserRepository $groupUserRepository;
public function __construct(
GroupUserRepository $groupUserRepository,
DoorGroupRepository $doorGroupRepository,
SchedulesRepository $schedulesRepository
) {
$this->doorGroupRepository = $doorGroupRepository;
$this->schedulesRepository = $schedulesRepository;
$this->groupUserRepository = $groupUserRepository;
}
/**
* @inheritDoc
*/
public function getUserDoorRelationships(string $userId, Presenter $presenter): void
{
$response = new ResponseModel();
$groups = $this->groupUserRepository->getGroupsForUser($userId);
foreach ($groups as $group) {
$response->addGroup($group);
$groupId = $group->getId();
$doors = $this->doorGroupRepository->getDoorsForGroup($groupId);
$schedules = $this->schedulesRepository->allForGroup($groupId);
foreach ($doors as $door) {
$response->addDoorToGroup($groupId, $door);
}
foreach ($schedules as $schedule) {
if ($schedule->hasTypeOf(Schedule::TYPE_USER_ACCESS)) {
$response->addScheduleToGroup($groupId, $schedule);
}
}
}
$presenter->present($response);
}
}
<?php
namespace Source\UseCases\DoorUser\UserDoorAccess;
interface UserDoorAccessUseCase
{
/**
* Gets a user and their door-schedule-group relationships
*
* @param string $userId
* @param \Source\UseCases\DoorUser\UserDoorAccess\Presenter $presenter
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function getUserDoorRelationships(string $userId, Presenter $presenter): void;
}
<?php
namespace Source\UseCases\DoorUser\UserDoorAccess;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Foundation\Application;
use Source\Gateways\DoorGroup\DoorGroupRepository;
use Source\Gateways\GroupUser\GroupUserRepository;
use Source\Gateways\Schedules\SchedulesRepository;
use Illuminate\Contracts\Support\DeferrableProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class UserDoorAccessUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(UserDoorAccessUseCase::class, static function (Application $app) {
return new UserDoorAccess(
$app->make(GroupUserRepository::class),
$app->make(DoorGroupRepository::class),
$app->make(SchedulesRepository::class)
);
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [UserDoorAccessUseCase::class];
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment