Skip to main content

Command Palette

Search for a command to run...

Laravelda Repository Pattern ni to'g'ri ishlatish

Updated
3 min read
<?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
{
    /**
     * @var Model
     */
    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
{
    /**
     * @param int   $id
     * @param array $columns
     * @param array $relations
     * @return Model
     * @throws ModelNotFoundException
     */
    public function findById(int $id, array $columns = ['*'], array $relations = []): Model;

    /**
     * @param string $uuid
     * @param array  $columns
     * @param array  $relations
     * @return Model
     * @throws ModelNotFoundException
     */
    public function findByUuid(string $uuid, array $columns = ['*'], array $relations = []): Model;

    /**
     * @param array $criteria
     * @param array $columns
     * @param array $relations
     * @return Model
     * @throws ModelNotFoundException
     */
    public function findByCriteria(array $criteria, array $columns = ['*'], array $relations = []): Model;

    /**
     * @param array $criteria
     * @param array $columns
     * @param array $relations
     * @return Collection
     */
    public function getByCriteria(array $criteria, array $columns = ['*'], array $relations = []): Collection;

    /**
     * @param array $attributes
     * @return Model
     */
    public function create(array $attributes): Model;

    /**
     * @param Model $model
     * @param array              $attributes
     * @return void
     */
    public function update(Model $model, array $attributes): void;

    /**
     * @param Model $model
     * @return void
     */
    public function delete(Model $model): void;

    /**
     * @return Builder
     */
    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,
            // All repositories are registered in this map
        ];

        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
    {
        // Other application related service providers
        $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
{
    /**
     * Find the user by email or username
     * @param string $identifier
     * @return User
     * @throws ModelNotFoundException
     */
    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); // Inject the model that you need to build queries from
    }

    public function findByLoginIdentifier(string $identifier): User
    {
        /** @var User $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
{
    /**
     * @var UserRepository
     */
    private UserRepository $userRepository;

    public function __construct(
        UserRepository $userRepository
    ) {
        $this->userRepository = $userRepository;
    }

    /**
     * @param LoginCredentialsDto $credentials
     * @return User
     * @throws HttpException
     */
    public function execute(LoginCredentialsDto $credentials): User
    {
        try {
            $user = $this->userRepository->findByLoginIdentifier($credentials->getIdentifier());
        } catch (ModelNotFoundException $exception) {
            throw new InvalidLoginCredentialsException;
        }

        // Rest of the login logic
        // 1. Validate the hashed password of the user instance
        // 2. Additional checks to verify that user is eligible for login

        return $user;
    }
}

More from this blog

Rashidov Nuriddin

34 posts