<?php
namespace Simplex\Patterns\Repositories;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Simplex\Patterns\Repositories\Contracts\RepositoryInterface;
class BaseRepository implements RepositoryInterface
{
private Model $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function findById(int $id, array $columns = ['*'], array $relations = []): Model
{
return $this->findByCriteria(['id' => $id], $columns, $relations);
}
public function findByUuid(string $uuid, array $columns = ['*'], array $relations = []): Model
{
return $this->findByCriteria(['uuid' => $uuid], $columns, $relations);
}
public function findByCriteria(array $criteria, array $columns = ['*'], array $relations = []): Model
{
return $this->newQuery()->select($columns)->with($relations)->where($criteria)->firstOrFail();
}
public function getByCriteria(array $criteria, array $columns = ['*'], array $relations = []): Collection
{
return $this->newQuery()->select($columns)->with($relations)->where($criteria)->get();
}
public function create(array $attributes): Model
{
return $this->newQuery()->create($attributes);
}
public function update(Model $model, array $attributes): void
{
$model->update($attributes);
}
public function delete(Model $model): void
{
$model->delete();
}
public function newQuery(): Builder
{
return $this->model->newQuery();
}
}
<?php
namespace Simplex\Patterns\Repositories\Contracts;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\ModelNotFoundException;
interface RepositoryInterface
{
public function findById(int $id, array $columns = ['*'], array $relations = []): Model;
public function findByUuid(string $uuid, array $columns = ['*'], array $relations = []): Model;
public function findByCriteria(array $criteria, array $columns = ['*'], array $relations = []): Model;
public function getByCriteria(array $criteria, array $columns = ['*'], array $relations = []): Collection;
public function create(array $attributes): Model;
public function update(Model $model, array $attributes): void;
public function delete(Model $model): void;
public function newQuery(): Builder;
}
<?php
namespace Simplex\Patterns\Repositories;
use Illuminate\Support\ServiceProvider;
use Simplex\Patterns\Repositories\User\PostgreUsers;
use Simplex\Patterns\Repositories\User\UserRepository;
class RepoServiceProvider extends ServiceProvider
{
public function register(): void
{
$toBind = [
UserRepository::class => PostgresUser::class,
];
foreach ($toBind as $interface => $implementation) {
$this->app->bind($interface, $implementation);
}
}
}
<?php
namespace App\Providers;
use Simplex\Patterns\Repositories\RepoServiceProvider;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->register(RepoServiceProvider::class);
}
}
<?php
namespace Simplex\Patterns\Repositories\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Simplex\Patterns\Contracts\RepositoryInterface;
use Simplex\Patterns\Models\Person\User;
interface UserRepository extends RepositoryInterface
{
public function findByLoginIdentifier(string $identifier): User;
}
<?php
namespace Simplex\Patterns\Repositories\Person\User;
use Illuminate\Database\Eloquent\Builder;
use Simplex\Pattern\Repositories\BaseRepository;
use Simplex\Pattern\Repositories\Models\User;
class PostgresUser extends BaseRepository implements UserRepository
{
public function __construct(User $model)
{
parent::__construct($model);
}
public function findByLoginIdentifier(string $identifier): User
{
$user = $this
->newQuery()
->where(function(Builder $builder) use ($identifier) {
$builder->where('email', $identifier);
$builder->orWhere('username', $identifier);
})
->firstOrFail();
return $user;
}
}
<?php
namespace Simplex\Patterns\Actions\Auth;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Simplex\Patterns\Repositories\User\UserRepository;
use Simplex\Patterns\Models\User;
use Simplex\Patterns\User\DTO\LoginCredentialsDto;
use Simplex\Patterns\User\Exceptions\Login\InvalidLoginCredentialsException;
class LoginUsingCredentialsAction
{
private UserRepository $userRepository;
public function __construct(
UserRepository $userRepository
) {
$this->userRepository = $userRepository;
}
public function execute(LoginCredentialsDto $credentials): User
{
try {
$user = $this->userRepository->findByLoginIdentifier($credentials->getIdentifier());
} catch (ModelNotFoundException $exception) {
throw new InvalidLoginCredentialsException;
}
return $user;
}
}