init commit
This commit is contained in:
345
app/Repositories/BaseRepository.php
Normal file
345
app/Repositories/BaseRepository.php
Normal file
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Interfaces\BaseRepositoryInterface;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
/**
|
||||
* Base Repository Implementation
|
||||
*
|
||||
* Provides common repository functionality for all models.
|
||||
* Implements the BaseRepositoryInterface with reusable methods.
|
||||
*
|
||||
* @author David Valera Melendez <david@valera-melendez.de>
|
||||
* @since February 2025
|
||||
*/
|
||||
abstract class BaseRepository implements BaseRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* The model instance
|
||||
*
|
||||
* @var Model
|
||||
*/
|
||||
protected Model $model;
|
||||
|
||||
/**
|
||||
* The query builder instance
|
||||
*
|
||||
* @var Builder
|
||||
*/
|
||||
protected Builder $query;
|
||||
|
||||
/**
|
||||
* Create a new repository instance
|
||||
*
|
||||
* @param Model $model
|
||||
*/
|
||||
public function __construct(Model $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->resetQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all records
|
||||
*
|
||||
* @param array $columns
|
||||
* @return Collection
|
||||
*/
|
||||
public function all(array $columns = ['*']): Collection
|
||||
{
|
||||
$result = $this->query->get($columns);
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get records with pagination
|
||||
*
|
||||
* @param int $perPage
|
||||
* @param array $columns
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function paginate(int $perPage = 15, array $columns = ['*']): LengthAwarePaginator
|
||||
{
|
||||
$result = $this->query->paginate($perPage, $columns);
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a record by ID
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $columns
|
||||
* @return Model|null
|
||||
*/
|
||||
public function find(int $id, array $columns = ['*']): ?Model
|
||||
{
|
||||
$result = $this->query->find($id, $columns);
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a record by ID or throw an exception
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $columns
|
||||
* @return Model
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail(int $id, array $columns = ['*']): Model
|
||||
{
|
||||
$result = $this->query->findOrFail($id, $columns);
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find records by criteria
|
||||
*
|
||||
* @param array $criteria
|
||||
* @param array $columns
|
||||
* @return Collection
|
||||
*/
|
||||
public function findBy(array $criteria, array $columns = ['*']): Collection
|
||||
{
|
||||
$this->applyCriteria($criteria);
|
||||
$result = $this->query->get($columns);
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a single record by criteria
|
||||
*
|
||||
* @param array $criteria
|
||||
* @param array $columns
|
||||
* @return Model|null
|
||||
*/
|
||||
public function findOneBy(array $criteria, array $columns = ['*']): ?Model
|
||||
{
|
||||
$this->applyCriteria($criteria);
|
||||
$result = $this->query->first($columns);
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new record
|
||||
*
|
||||
* @param array $data
|
||||
* @return Model
|
||||
*/
|
||||
public function create(array $data): Model
|
||||
{
|
||||
return $this->model->create($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing record
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $data
|
||||
* @return bool
|
||||
*/
|
||||
public function update(int $id, array $data): bool
|
||||
{
|
||||
$model = $this->findOrFail($id);
|
||||
return $model->update($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update or create a record
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param array $values
|
||||
* @return Model
|
||||
*/
|
||||
public function updateOrCreate(array $attributes, array $values = []): Model
|
||||
{
|
||||
return $this->model->updateOrCreate($attributes, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a record by ID
|
||||
*
|
||||
* @param int $id
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(int $id): bool
|
||||
{
|
||||
$model = $this->findOrFail($id);
|
||||
return $model->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete records by criteria
|
||||
*
|
||||
* @param array $criteria
|
||||
* @return int Number of deleted records
|
||||
*/
|
||||
public function deleteBy(array $criteria): int
|
||||
{
|
||||
$this->applyCriteria($criteria);
|
||||
$result = $this->query->delete();
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count records
|
||||
*
|
||||
* @param array $criteria
|
||||
* @return int
|
||||
*/
|
||||
public function count(array $criteria = []): int
|
||||
{
|
||||
if (!empty($criteria)) {
|
||||
$this->applyCriteria($criteria);
|
||||
}
|
||||
|
||||
$result = $this->query->count();
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if record exists
|
||||
*
|
||||
* @param array $criteria
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(array $criteria): bool
|
||||
{
|
||||
$this->applyCriteria($criteria);
|
||||
$result = $this->query->exists();
|
||||
$this->resetQuery();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get records with relationships
|
||||
*
|
||||
* @param array $relations
|
||||
* @return BaseRepositoryInterface
|
||||
*/
|
||||
public function with(array $relations): BaseRepositoryInterface
|
||||
{
|
||||
$this->query = $this->query->with($relations);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order records
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $direction
|
||||
* @return BaseRepositoryInterface
|
||||
*/
|
||||
public function orderBy(string $column, string $direction = 'asc'): BaseRepositoryInterface
|
||||
{
|
||||
$this->query = $this->query->orderBy($column, $direction);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit records
|
||||
*
|
||||
* @param int $limit
|
||||
* @return BaseRepositoryInterface
|
||||
*/
|
||||
public function limit(int $limit): BaseRepositoryInterface
|
||||
{
|
||||
$this->query = $this->query->limit($limit);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply criteria to the query
|
||||
*
|
||||
* @param array $criteria
|
||||
* @return void
|
||||
*/
|
||||
protected function applyCriteria(array $criteria): void
|
||||
{
|
||||
foreach ($criteria as $field => $value) {
|
||||
if (is_array($value)) {
|
||||
$this->query = $this->query->whereIn($field, $value);
|
||||
} elseif (is_null($value)) {
|
||||
$this->query = $this->query->whereNull($field);
|
||||
} else {
|
||||
$this->query = $this->query->where($field, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the query builder
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function resetQuery(): void
|
||||
{
|
||||
$this->query = $this->model->newQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model instance
|
||||
*
|
||||
* @return Model
|
||||
*/
|
||||
public function getModel(): Model
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the model instance
|
||||
*
|
||||
* @param Model $model
|
||||
* @return void
|
||||
*/
|
||||
public function setModel(Model $model): void
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->resetQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback within a database transaction
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return mixed
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function transaction(callable $callback)
|
||||
{
|
||||
return $this->model->getConnection()->transaction($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fresh timestamp for the model
|
||||
*
|
||||
* @return \Carbon\Carbon
|
||||
*/
|
||||
protected function freshTimestamp(): \Carbon\Carbon
|
||||
{
|
||||
return $this->model->freshTimestamp();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user