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

Add gateways for attempts and entries

parent 3ec81fc5
......@@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Attempt extends Model
{
protected $fillable = ['door_id'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
......
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttemptsTable extends Migration
{
......
<?php
namespace Source\Entities;
use Carbon\Carbon;
class Attempt
{
/**
* @var int
*/
protected int $id;
/**
* @var int
*/
protected int $doorId;
/**
* @var \Carbon\Carbon|null
*/
protected ?Carbon $createdAt;
/**
* @var \Carbon\Carbon|null
*/
protected ?Carbon $updatedAt;
public function __construct(
int $id,
int $doorId,
?Carbon $createdAt = null,
?Carbon $updatedAt = null
) {
$this->id = $id;
$this->doorId = $doorId;
$this->createdAt = $createdAt;
$this->updatedAt = $updatedAt;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return int
*/
public function getDoorId(): int
{
return $this->doorId;
}
/**
* @return \Carbon\Carbon|null
*/
public function getCreatedAt(): ?Carbon
{
return $this->createdAt;
}
/**
* @return \Carbon\Carbon|null
*/
public function getUpdatedAt(): ?Carbon
{
return $this->updatedAt;
}
/**
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return bool
*/
public function isBetween(Carbon $begin, Carbon $end): bool
{
return $this->createdAt->isBetween($begin, $end);
}
/**
* @param string|null $doorId
* @return bool
*/
public function hasDoorIdOf(?string $doorId): bool
{
if (!$doorId) {
return false;
}
return $this->getDoorId() === (int)$doorId;
}
}
<?php
namespace Source\Entities;
use Carbon\Carbon;
class Entry
{
/**
* @var int
*/
protected int $id;
/**
* @var int
*/
protected int $userId;
/**
* @var int
*/
protected int $doorId;
/**
* @var \Carbon\Carbon|null
*/
protected ?Carbon $createdAt;
/**
* @var \Carbon\Carbon|null
*/
protected ?Carbon $updatedAt;
public function __construct(
int $id,
int $userId,
int $doorId,
?Carbon $createdAt = null,
?Carbon $updatedAt = null
) {
$this->id = $id;
$this->userId = $userId;
$this->doorId = $doorId;
$this->createdAt = $createdAt;
$this->updatedAt = $updatedAt;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @return int
*/
public function getUserId(): int
{
return $this->userId;
}
/**
* @return int
*/
public function getDoorId(): int
{
return $this->doorId;
}
/**
* @return \Carbon\Carbon|null
*/
public function getCreatedAt(): ?Carbon
{
return $this->createdAt;
}
/**
* @return \Carbon\Carbon|null
*/
public function getUpdatedAt(): ?Carbon
{
return $this->updatedAt;
}
/**
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return bool
*/
public function isBetween(Carbon $begin, Carbon $end): bool
{
return $this->createdAt->isBetween($begin, $end);
}
/**
* @param string|null $userId
* @return bool
*/
public function hasUserIdOf(?string $userId): bool
{
if (!$userId) {
return false;
}
return $this->getUserId() === (int)$userId;
}
/**
* @param string|null $doorId
* @return bool
*/
public function hasDoorIdOf(?string $doorId): bool
{
if (!$doorId) {
return false;
}
return $this->getDoorId() === (int)$doorId;
}
}
<?php
namespace Source\Gateways\Attempts;
use Carbon\Carbon;
use Source\Entities\Attempt;
interface AttemptsRepository
{
/**
* @param \Source\Entities\Attempt $attempt
* @return bool
*/
public function add(Attempt $attempt): bool;
/**
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return \Source\Entities\Attempt[]
*/
public function getBetween(Carbon $begin, Carbon $end): array;
/**
* @param string $doorId
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return \Source\Entities\Attempt[]
*/
public function getForDoorBetween(string $doorId, Carbon $begin, Carbon $end): array;
/**
* @param string $doorId
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return int
*/
public function getCountForDoorBetween(string $doorId, Carbon $begin, Carbon $end): int;
}
<?php
namespace Source\Gateways\Attempts;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\DeferrableProvider;
/**
* Service provider must be registered in AppServiceProvider
*/
class AttemptsRepositoryServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton(AttemptsRepository::class, static function (Application $app) {
if (env('APP_ENV') === 'memory') {
return new LocalAttemptsRepository();
}
if (env('APP_ENV') === 'testing') {
return new InMemoryAttemptsRepository();
}
return new DatabaseAttemptsRepository();
});
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(): void
{
}
/**
* @return array
*/
public function provides()
{
return [AttemptsRepository::class];
}
}
<?php
namespace Source\Gateways\Attempts;
use Carbon\Carbon;
use Source\Entities\Attempt;
use Source\Sanitize\CastsTo;
class DatabaseAttemptsRepository implements AttemptsRepository
{
use CastsTo;
/**
* @param \App\Attempt $attempt
* @return \Source\Entities\Attempt
*/
protected static function toAttempt(\App\Attempt $attempt): Attempt
{
return new Attempt(
$attempt->id,
$attempt->door_id,
$attempt->created_at,
$attempt->updated_at
);
}
/**
* @inheritDoc
*/
public function getBetween(Carbon $begin, Carbon $end): array
{
$attempts = \App\Attempt::whereBetween('created_at', [$begin, $end])->get();
return array_map(static function (\App\Attempt $attempt) {
return self::toAttempt($attempt);
}, $attempts);
}
/**
* @inheritDoc
*/
public function getForDoorBetween(string $doorId, Carbon $begin, Carbon $end): array
{
$attempts = \App\Attempt::where('door_id', $this->castToInt($doorId))
->whereBetween('created_at', [$begin, $end])
->get();
return array_map(static function (\App\Attempt $attempt) {
return self::toAttempt($attempt);
}, $attempts);
}
/**
* @inheritDoc
*/
public function getCountForDoorBetween(string $doorId, Carbon $begin, Carbon $end): int
{
return \App\Attempt::where('door_id', $this->castToInt($doorId))
->whereBetween('created_at', [$begin, $end])
->count();
}
/**
* @inheritDoc
*/
public function add(Attempt $attempt): bool
{
$a = new \App\Attempt();
$a->door_id = $attempt->getId();
return $a->save();
}
}
<?php
namespace Source\Gateways\Attempts;
use Carbon\Carbon;
use Source\Entities\Attempt;
class InMemoryAttemptsRepository implements AttemptsRepository
{
/**
* @var \Source\Entities\Attempt[]
*/
protected array $attempts = [];
/**
* @inheritDoc
*/
public function add(Attempt $attempt): bool
{
$this->attempts[] = $attempt;
return true;
}
/**
* @inheritDoc
*/
public function getBetween(Carbon $begin, Carbon $end): array
{
return array_values(array_filter($this->attempts, static function (Attempt $attempt) use ($begin, $end) {
return $attempt->isBetween($begin, $end);
}));
}
/**
* @inheritDoc
*/
public function getForDoorBetween(string $doorId, Carbon $begin, Carbon $end): array
{
return array_values(array_filter($this->attempts, static function (Attempt $attempt) use ($doorId, $begin, $end) {
return $attempt->isBetween($begin, $end) && $attempt->hasDoorIdOf($doorId);
}));
}
/**
* @inheritDoc
*/
public function getCountForDoorBetween(string $doorId, Carbon $begin, Carbon $end): int
{
return count(array_filter($this->attempts, static function (Attempt $attempt) use ($doorId, $begin, $end) {
return $attempt->isBetween($begin, $end) && $attempt->hasDoorIdOf($doorId);
}));
}
}
<?php
namespace Source\Gateways\Attempts;
class LocalAttemptsRepository extends InMemoryAttemptsRepository
{
}
<?php
namespace Source\Gateways\Entries;
use Carbon\Carbon;
use Source\Entities\Entry;
use Source\Sanitize\CastsTo;
class DatabaseEntriesRepository implements EntriesRepository
{
use CastsTo;
/**
* @param \App\Entry $entry
* @return \Source\Entities\Entry
*/
protected static function toEntry(\App\Entry $entry): Entry
{
return new Entry(
$entry->id,
$entry->user_id,
$entry->door_id,
$entry->created_at,
$entry->updated_at
);
}
/**
* @inheritDoc
*/
public function getForUserBetween(string $userId, Carbon $begin, Carbon $end): array
{
$entries = \App\Entry::where('user_id', $this->castToInt($userId))
->whereBetween('created_at', [$begin, $end])
->get();
return array_map(static function (\App\Entry $entry) {
return self::toEntry($entry);
}, $entries);
}
/**
* @inheritDoc
*/
public function getForDoorBetween(string $doorId, Carbon $begin, Carbon $end): array
{
$entries = \App\Entry::where('door_id', $this->castToInt($doorId))
->whereBetween('created_at', [$begin, $end])
->get();
return array_map(static function (\App\Entry $entry) {
return self::toEntry($entry);
}, $entries);
}
/**
* @inheritDoc
*/
public function getForUserAndDoorBetween(string $userId, string $doorId, Carbon $begin, Carbon $end): array
{
$entries = \App\Entry::where('user_id', $this->castToInt($userId))
->where('door_id', $this->castToInt($doorId))
->whereBetween('created_at', [$begin, $end])
->get();
return array_map(static function (\App\Entry $entry) {
return self::toEntry($entry);
}, $entries);
}
/**
* @inheritDoc
*/
public function add(Entry $entry): bool
{
$e = new \App\Entry();
$e->user_id = $entry->getUserId();
$e->door_id = $entry->getDoorId();
return $e->save();
}
}
<?php
namespace Source\Gateways\Entries;
use Carbon\Carbon;
use Source\Entities\Entry;
interface EntriesRepository
{
/**
* @param \Source\Entities\Entry $entry
* @return bool
*/
public function add(Entry $entry): bool;
/**
* @param string $userId
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return \Source\Entities\Entry[]
*/
public function getForUserBetween(string $userId, Carbon $begin, Carbon $end): array;
/**
* @param string $doorId
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return \Source\Entities\Entry[]
*/
public function getForDoorBetween(string $doorId, Carbon $begin, Carbon $end): array;
/**
* @param string $userId
* @param string $doorId
* @param \Carbon\Carbon $begin
* @param \Carbon\Carbon $end
* @return \Source\Entities\Entry[]
*/
public function getForUserAndDoorBetween(string $userId, string $doorId, Carbon $begin, Carbon $end): array;
}