ldc-arcadia-api/src/Infra/Adapters/Repositories/ApiClientRepository.php

134 lines
4 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Infra\Adapters\Repositories;
use Application\Security\Exceptions\ClientNotFoundException;
use Application\Security\Models\Entities\Client;
use Application\Security\Models\ValueObjects\ClientIdentifier;
use Application\Security\Models\ValueObjects\ClientName;
use Application\Security\Models\ValueObjects\Entities\ClientId;
use Application\Security\Ports\Repositories\ClientRepository;
use Illuminate\Support\Str;
use Infra\Database\Models\ApiClient;
use Shared\Paginated;
use Shared\Pagination;
final class ApiClientRepository implements ClientRepository
{
#[\Override]
public function persist(Client $client): void
{
ApiClient::query()->updateOrCreate(
['id' => $client->id->value],
[
'name' => $client->name,
'slug' => Str::slug($client->name->value),
'identifier' => $client->identifier,
'secret' => $client->secret,
'is_active' => $client->isActive,
]
);
}
#[\Override]
public function existsByName(ClientName $name): bool
{
return ApiClient::query()
->where('slug', Str::slug($name->value))
->exists();
}
#[\Override]
public function findByIdentifier(ClientIdentifier $identifier): ?Client
{
return transform(
ApiClient::query()
->where('identifier', $identifier->value)
->first(),
fn (ApiClient $apiClient) => $this->toDomain($apiClient)
);
}
#[\Override]
public function find(ClientId $id): ?Client
{
return transform(
ApiClient::query()->where('id', $id->value)->first(),
fn (ApiClient $apiClient) => $this->toDomain($apiClient)
);
}
#[\Override]
public function search(string $query, Pagination $pagination): Paginated
{
$trimmed = trim($query);
if ($trimmed === '') {
return new Paginated($pagination, [], 0);
}
$term = '%' . strtolower($trimmed) . '%';
$builder = ApiClient::query()
->where(function ($b) use ($term): void {
$b->whereRaw('LOWER(name) LIKE ?', [$term])
->orWhereRaw('LOWER(slug) LIKE ?', [$term])
->orWhereRaw('LOWER(identifier) LIKE ?', [$term])
->orWhereRaw('LOWER(id) LIKE ?', [$term]);
});
$total = $builder->count();
$items = $builder->forPage(
$pagination->pageNumber(),
$pagination->pageSize()
)->get();
return new Paginated(
pagination: $pagination,
items: $items->map(fn (ApiClient $apiClient) => $this->toDomain($apiClient))->all(),
total: $total,
);
}
#[\Override]
public function findAll(Pagination $pagination): Paginated
{
$query = ApiClient::query();
$total = $query->count();
$items = $query->forPage(
$pagination->pageNumber(),
$pagination->pageSize()
)->get();
return new Paginated(
pagination: $pagination,
items: $items->map(fn (ApiClient $apiClient) => $this->toDomain($apiClient))->all(),
total: $total,
);
}
#[\Override]
public function delete(Client $client): void
{
$deleted = ApiClient::query()->where('id', $client->id->value)->delete();
if ($deleted === 0) {
throw ClientNotFoundException::forClient($client->id->value);
}
}
private function toDomain(ApiClient $apiClient): Client
{
return Client::hydrate(
id: new ClientId($apiClient->id),
name: $apiClient->name,
identifier: $apiClient->identifier,
secret: $apiClient->secret,
isActive: $apiClient->is_active,
createdAt: $apiClient->created_at,
updatedAt: $apiClient->updated_at,
);
}
}