Commit c0c5c4f0 authored by Jacob Priddy's avatar Jacob Priddy 👌
Browse files

Add update doors endpoint and usecase

parent 6aec333b
......@@ -5,6 +5,8 @@ namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Source\Authorization\Permissions;
use Source\UseCases\Doors\GetDoor\GetDoorUseCase;
use Source\UseCases\Doors\UpdateDoor\APIPresenter as UpdateDoorAPIPresenter;
use Source\UseCases\Doors\UpdateDoor\UpdateDoorUseCase;
use Source\UseCases\Doors\CreateDoor\APIPresenter as CreateDoorAPIPresenter;
use Source\UseCases\Doors\CreateDoor\CreateDoorUseCase;
use Source\UseCases\Doors\GetAllDoors\GetAllDoorsUseCase;
......@@ -62,13 +64,33 @@ class DoorsController extends ApiController
]);
$presenter = new CreateDoorAPIPresenter();
$attributes = $this->request->all();
$attributes['salt'] = config('app.key');
$createDoor->create($attributes, $presenter);
return $this->respondWithData($presenter->getViewModel());
}
/**
* @param \Source\UseCases\Doors\UpdateDoor\UpdateDoorUseCase $updateDoor
* @param string $doorId
* @return \Illuminate\Http\JsonResponse
* @throws \Illuminate\Validation\ValidationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function update(UpdateDoorUseCase $updateDoor, string $doorId): JsonResponse
{
$this->validate($this->request, [
'location' => 'string|max:255',
'name' => 'string|max:255',
]);
$presenter = new UpdateDoorAPIPresenter();
$attributes = $this->request->all();
$updateDoor->update($doorId, $attributes, $presenter);
return $this->respondWithData($presenter->getViewModel());
}
}
......@@ -17,6 +17,7 @@ use Source\UseCases\Users\CreateUser\CreateUserUseCaseServiceProvider;
use Source\UseCases\Users\DeleteUser\DeleteUserUseCaseServiceProvider;
use Source\UseCases\Users\UpdateUser\UpdateUserUseCaseServiceProvider;
use Source\UseCases\Doors\CreateDoor\CreateDoorUseCaseServiceProvider;
use Source\UseCases\Doors\UpdateDoor\UpdateDoorUseCaseServiceProvider;
use Source\UseCases\Users\GetAllUsers\GetAllUsersUseCaseServiceProvider;
use Source\UseCases\Doors\GetAllDoors\GetAllDoorsUseCaseServiceProvider;
use Source\UseCases\Groups\CreateGroup\CreateGroupUseCaseServiceProvider;
......@@ -73,6 +74,7 @@ class AppServiceProvider extends ServiceProvider
// Doors
GetDoorUseCaseServiceProvider::class,
CreateDoorUseCaseServiceProvider::class,
UpdateDoorUseCaseServiceProvider::class,
GetAllDoorsUseCaseServiceProvider::class,
AuthenticateUseCaseServiceProvider::class,
DoorAuthenticateUseCaseServiceProvider::class,
......
......@@ -55,7 +55,8 @@ Route::group(['middleware' => 'auth:api'], static function () {
Route::get('/', [DoorsController::class, 'index']);
Route::post('/', [DoorsController::class, 'store']);
Route::get('{doorId}', [DoorsController::class, 'get']);
// Route::put('{doorId}', [DoorsController::class, 'update']);
Route::put('{doorId}', [DoorsController::class, 'update']);
// Route::post('/{doorId}/regenerate-token', [DoorsController::class, 'regenerateToken']);
// Route::delete('{doorId}', [DoorsController::class, 'delete']);
});
......
......@@ -121,4 +121,12 @@ class Door
return $this->id === (int)$id;
}
/**
* @param string $id
*/
public function setId(string $id): void
{
$this->id = $id;
}
}
......@@ -94,4 +94,23 @@ class DatabaseDoorsRepository implements DoorsRepository
return \App\Door::where('name', $name)->first();
}
/**
* @inheritDoc
*/
public function update(string $doorId, Door $door): ?Door
{
$dbDoor = \App\Door::find((int)$doorId);
if (!$dbDoor) {
return null;
}
$dbDoor->name = $door->getName();
$dbDoor->location = $door->getLocation();
$dbDoor->save();
return self::makeDoorFromDb($dbDoor);
}
}
......@@ -45,4 +45,11 @@ interface DoorsRepository
* @return \Source\Entities\Door|null
*/
public function findByName(?string $name): ?Door;
/**
* @param string $doorId
* @param \Source\Entities\Door $door
* @return \Source\Entities\Door|null
*/
public function update(string $doorId, Door $door): ?Door;
}
......@@ -75,4 +75,22 @@ class InMemoryDoorsRepository implements DoorsRepository
return null;
}
/**
* @inheritDoc
*/
public function update(string $doorId, Door $door): ?Door
{
foreach ($this->doors as &$doorBase) {
if ($doorBase->hasIdOf($doorId)) {
$door->setId($doorBase->getId());
$doorBase = $door;
return $doorBase;
}
}
return null;
}
}
......@@ -80,11 +80,15 @@ abstract class BasePresenter
}
/**
* @param \Source\Entities\Door $door
* @param \Source\Entities\Door|null $door
* @return array
*/
public function formatDoor(Door $door): array
public function formatDoor(?Door $door): array
{
if (!$door) {
return null;
}
return [
'id' => $door->getId(),
'name' => $door->getName(),
......
<?php
namespace Source\UseCases\Doors\UpdateDoor;
use Source\UseCases\BasePresenter;
class APIPresenter extends BasePresenter implements Presenter
{
protected array $viewModel = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$this->viewModel['message'] = $responseModel->getMessage();
$this->viewModel['door'] = $this->formatDoor($responseModel->getDoor());
}
/** @inheritDoc */
public function getViewModel(): array
{
return $this->viewModel;
}
}
<?php
namespace Source\UseCases\Doors\UpdateDoor;
interface Presenter
{
/**
* @param ResponseModel $responseModel
* @return void
*/
public function present(ResponseModel $responseModel): void;
/**
* @return array
*/
public function getViewModel(): array;
}
<?php
namespace Source\UseCases\Doors\UpdateDoor;
use Source\Entities\Door;
class ResponseModel
{
/**
* @var \Source\Entities\Door|null
*/
protected ?Door $door = null;
/**
* @var string
*/
protected string $message = '';
/**
* @param \Source\Entities\Door|null $door
*/
public function __construct(?Door $door)
{
$this->door = $door;
}
/**
* @return \Source\Entities\Door|null
*/
public function getDoor(): ?Door
{
return $this->door;
}
/**
* @param string $message
*/
public function setMessage(string $message): void
{
$this->message = $message;
}
/**
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
}
<?php
namespace Source\UseCases\Doors\UpdateDoor;
use Source\Entities\Door;
use Source\Gateways\Doors\DoorsRepository;
use Source\Exceptions\EntityNotFoundException;
class UpdateDoor implements UpdateDoorUseCase
{
/**
* @var \Source\Gateways\Doors\DoorsRepository
*/
protected DoorsRepository $doors;
/**
* @param \Source\Gateways\Doors\DoorsRepository $doors
*/
public function __construct(DoorsRepository $doors)
{
$this->doors = $doors;
}
/**
* @inheritDoc
*/
public function update(string $doorId, array $attributes, Presenter $presenter)
{
$door = $this->doors->get($doorId);
if (!$door) {
throw new EntityNotFoundException();
}
$newDoor = new Door(
$door->getId(),
$attributes['location'] ?? $door->getLocation(),
$attributes['name'] ?? $door->getName(),
$door->getToken(),
$door->getCreatedAt(),
$door->getUpdatedAt()
);
$returnedDoor = $this->doors->update($door->getId(), $newDoor);
$response = new ResponseModel($returnedDoor);
if (!$returnedDoor) {
$response->setMessage('Unable to update door.');
} else {
$response->setMessage('Successfully updated door.');
}
$presenter->present($response);
}
}
<?php
namespace Source\UseCases\Doors\UpdateDoor;
interface UpdateDoorUseCase
{
/**
* Optional attributes
* name
* location
*
* @param string $doorId
* @param array $attributes
* @param \Source\UseCases\Doors\UpdateDoor\Presenter $presenter
* @return mixed
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function update(string $doorId, array $attributes, Presenter $presenter);
}
<?php
namespace Source\UseCases\Doors\UpdateDoor;
use Source\Gateways\Doors\DoorsRepository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class UpdateDoorUseCaseServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(UpdateDoorUseCase::class, static function (Application $app) {
return new UpdateDoor($app->make(DoorsRepository::class));
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [UpdateDoorUseCase::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