Skip to content

Instantly share code, notes, and snippets.

@fgonga
Created November 1, 2024 23:46
Show Gist options
  • Save fgonga/0aab0bb50c53dbced77407bd7354d273 to your computer and use it in GitHub Desktop.
Save fgonga/0aab0bb50c53dbced77407bd7354d273 to your computer and use it in GitHub Desktop.
Implemente Repository Pattener with
<?php
namespace Modules\Maintenance\src\asset\repositories;
use Modules\Core\src\abstracts\EloquentRepositoryAbstract;
use Modules\Core\src\contracts\EloquentRepositoryInterface;
use Modules\Maintenance\app\Models\MaintenanceAsset;
class AssetRepository extends EloquentRepositoryAbstract implements EloquentRepositoryInterface
{
/**
* LocationRepository constructor.
*/
public function __construct()
{
$this->model = new MaintenanceAsset();
}
}
<?php
namespace Modules\Core\src\abstracts;
use Modules\Core\src\contracts\EloquentRepositoryInterface;
use Modules\Core\src\exceptions\InvalidDataProvidedException;
use Modules\Core\src\exceptions\RepositoriesException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use Modules\Maintenance\src\generic\dtos\PaginationRequestDTO;
abstract class EloquentRepositoryAbstract implements EloquentRepositoryInterface {
public $model;
protected $query;
/**
* @var array $data
* query parameters (sort, filters, pagination)
*/
protected $data;
protected $filters = [];
protected $with = [];
protected $columns = ['*'];
protected $orderBy = 'id';
protected $sortMethod = 'DESC';
protected $limit = 300;
protected $offset = 0;
protected $search = '';
protected $searchable = [];
public function __construct() {
$this->orderBy = 'id';
}
public function when(string $name,array $data){
if(array_key_exists($name, $data)){
if ($data[$name] !== null) {
return true;
}
}
return false;
}
public function index(PaginationRequestDTO $requestDTO){
return $this->filters($requestDTO)
->with($requestDTO->with)
->columns($requestDTO->columns)
->paginate($requestDTO->perPage);
}
public function filters(PaginationRequestDTO $pagination)
{
$filters = $pagination->filters;
// Verificar se o primeiro elemento é uma string JSON válida e converter todos os elementos
if (is_array($filters) && isset($filters[0]) && is_string($filters[0])) {
$filters = array_map(static function ($filter) {
return is_string($filter) ? json_decode($filter, true) : $filter;
}, $filters);
}
$this->filters = $filters;
$this->search = $pagination->search;
$this->searchable = $pagination->searchable;
return $this;
}
public function findFirst(){
return $this->makeQuery()->first($this->columns);
}
public function update($date){
if (is_array($date) === false) {
throw new RepositoriesException('');
}
return $this->model->update($date);
}
public function delete(){
return $this->model->delete();
}
/**
* @param array $with
* @return $this
* @throws RepositoriesException
*/
public function with(array $with = []) {
if (is_array($with) === false) {
throw new RepositoriesException('');
}
$this->with = $with;
return $this;
}
/**
* @param array $columns
* @return $this
* @throws RepositoriesException
*/
public function columns(array $columns = ['*']) {
if (is_array($columns) === false) {
throw new RepositoriesException('');
}
$this->columns = $columns;
return $this;
}
/**
* @param int $limit
* @return $this
* @throws RepositoriesException
*/
public function limit($limit = 10) {
if (!is_numeric($limit) || $limit < 1) {
throw new RepositoriesException('Limit Must be greater than 1');
}
$this->limit = $limit;
return $this;
}
/**
* @param $id
* @param $field
*/
public function inc($id, $field) {
$this->model->findOrFail($id)->increment($field);
}
/**
* @param $id
* @param $field
*/
public function dec($id, $field) {
$this->model->find($id)->decrement($field);
}
/**
* @param int $offset
* @return $this
* @throws RepositoriesException
*/
public function offset($offset = 0) {
if (!is_numeric($offset) || $offset < 0) {
throw new RepositoriesException('Offset must be grater than or equal to ZERO');
}
$this->offset = $offset;
return $this;
}
/**
* @param $orderBy
* @param string $sort
* @return $this
* @throws RepositoriesException
*/
public function orderBy($orderBy = null, $sort = 'ASC') {
if ($orderBy === null) {
return $this;
}
$this->orderBy = $orderBy;
if (!in_array(strtoupper($sort), ['DESC', 'ASC'])) {
throw new RepositoriesException('');
}
$this->sortMethod = $sort;
return $this;
}
public function makeQuery() {
$query = $this->model->query();
foreach ($this->filters as $filter) {
$field = $filter['field'] ?? null;
$operator = $filter['operator'] ?? '=';
$value = $filter['value'] ?? null;
// Verifica se o campo e o valor foram passados
if ($field && $value !== null) {
// Aplica o filtro à query de forma dinâmica
$query->where($field, $operator, $value);
}
}
$search = $this->search;
$searchable = $this->searchable;
if ($this->search) {
$query->where(function($q) use ($searchable, $search) {
foreach ($searchable as $column) {
$q->orWhere($column, 'like', '%' .$search. '%');
}
});
}
return $query;
}
/**
* @param array $data
* @return mixed
*/
public function create() {
return [];
}
/**
* @param array $data
* @return mixed
*/
public function store(array $data) {
return $this->model->create($data);
}
public function findById($id) {
$model = $this->model->where("id", "=", $id)->get()->first();
if ($model != null) {
return $model;
}
}
/**
* @param $id
* @return mixed
*/
public function findOneById($id) {
return $this->makeQuery()
->with($this->with)
->findOrFail($id, $this->columns);
}
/**
* @param array $ids
* @return mixed
*/
public function findManyByIds(array $ids) {
return $this->makeQuery()
->with($this->with)
->orderBy($this->orderBy, $this->sortMethod)
->whereIn($this->model->getKeyName(), $ids)
->take($this->limit)
->skip($this->offset)
->get($this->columns);
}
/**
* @param $key
* @param $value
* @return mixed
*/
public function findOneBy($key, $value) {
return $this->makeQuery()
->with($this->with)
->where($key, '=', $value)
->first($this->columns);
}
/**
* @param $key
* @param $value
* @return mixed
*/
public function findOneByNotRaiseException($key, $value) {
return $this->makeQuery()
->with($this->with)
->where($key, '=', $value)
->first($this->columns);
}
/**
* @param $key
* @param $value
* @return Collection
*/
public function findManyBy($key, $value) {
return $this->makeQuery()
->with($this->with)
->where($key, '=', $value)
->orderBy($this->orderBy, $this->sortMethod)
->take($this->limit)
->skip($this->offset)
->get($this->columns);
}
/**
* @return Collection
*/
public function findAll() {
return $this->makeQuery()
->with($this->with)
->orderBy($this->orderBy, $this->sortMethod)
->get($this->columns);
}
/**
* @return Collection
*/
public function findMany() {
return $this->makeQuery()
->with($this->with)
->orderBy($this->orderBy, $this->sortMethod)
->take($this->limit)
->skip($this->offset)
->get($this->columns);
}
/**
* @param array $credentials
* @return Collection
*/
public function findManyByCredentials(array $credentials = []) {
return $this->buildCredentialsQuery($credentials)
->with($this->with)
->orderBy($this->orderBy, $this->sortMethod)
->take($this->limit)
->skip($this->offset)
->get($this->columns);
}
/**
* @param array $credentials
* @return Collection | ModelNotFoundException
*/
public function findOneByCredentials(array $credentials = []) {
return $this->buildCredentialsQuery($credentials)
->with($this->with)
->firstOrFail($this->columns);
}
/**
* @param $key
* @param $value
* @param int $perPage
* @return mixed
*/
public function paginateBy($key, $value, $perPage = 10) {
return $this->makeQuery()
->with($this->with)
->where($key, '=', $value)
->orderBy($this->orderBy, $this->sortMethod)
->paginate($perPage, $this->columns);
}
/**
* @param int $perPage
* @return mixed
*/
public function paginate($perPage = 10) {
return $this->makeQuery()
->with($this->with)
->orderBy($this->orderBy, $this->sortMethod)
->paginate($perPage, $this->columns);
}
/**
* @param $query
* @param int $perPage
* @return mixed
*/
public function paginateQuery($query, $perPage = 10) {
return $query->orderBy($this->orderBy, $this->sortMethod)
->paginate($perPage, $this->columns);
}
/**
* @param $credentials
* @param int $perPage
* @return Paginator
*/
public function paginateByCredentials($credentials, $perPage = 10) {
return $this->buildCredentialsQuery($credentials)
->with($this->with)
->orderBy($this->orderBy, $this->sortMethod)
->paginate($perPage, $this->columns);
}
/**
* @param $id
* @param array $data
* @return bool
* @throws InvalidDataProvidedException
*/
public function updateOneById($id, array $data = []) {
if (!is_array($data) || empty($data))
throw new InvalidDataProvidedException;
return $this->makeQuery()
->findOrFail($id)
->update($data);
}
/**
* @param $key
* @param $value
* @param array $data
* @return bool
* @throws InvalidDataProvidedException
*/
public function updateOneBy($key, $value, array $data = []) {
if (is_array($data) || empty($data))
throw new InvalidDataProvidedException;
return $this->makeQuery()
->where($key, '=', $value)
->firstOrFail()
->update($data);
}
/**
* @param array $credentials
* @param array $data
* @return bool
* @throws InvalidDataProvidedException
*/
public function updateOneByCredentials(array $credentials, array $data = []) {
if (is_array($data) || empty($data))
throw new InvalidDataProvidedException;
return $this->buildCredentialsQuery($credentials)
->firstOrFail()
->update($data);
}
/**
* @param $key
* @param $value
* @param array $data
* @return bool
* @throws InvalidDataProvidedException
*/
public function updateManyBy($key, $value, array $data = []) {
if (is_array($data) || empty($data)){
throw new InvalidDataProvidedException;
}
return $this->makeQuery()
->where($key, $value)
->take($this->limit)
->skip($this->offset)
->update($data);
}
/**
* @param array $ids
* @param array $data
* @return bool
* @throws InvalidDataProvidedException
*/
public function updateManyByIds(array $ids, array $data = []) {
if (!is_array($data) || empty($data))
throw new InvalidDataProvidedException;
return $this->makeQuery()
->whereIn('id', $ids)
->update($data);
}
/**
* @param array $ids
* @return bool
*/
public function allExist(array $ids) {
return (count($ids) == $this->makeQuery()->whereIn('id', $ids)->count());
}
/**
* @param array $credentials
* @param array $data
* @return boolean
*/
public function updateManyByCredentials(array $credentials = [], array $data = []) {
return $this->buildCredentialsQuery($credentials)->update($data);
}
/**
* @param array $credentials
* @param array $data
* @return mixed
*/
public function updateAllByCredentials(array $credentials = [], array $data = []) {
return $this->buildCredentialsQuery($credentials)
->update($data);
}
/**
* @param $id
* @return boolean
*/
public function deleteOneById($id) {
return $this->makeQuery()
->findOrFail($id)
->delete();
}
/**
* @param $key
* @param $value
* @return boolean
*/
public function deleteOneBy($key, $value) {
return $this->makeQuery()
->where($key, '=', $value)
->firstOrFail()
->delete();
}
/**
* @param array $credentials
* @return boolean
*/
public function deleteOneByCredentials(array $credentials = []) {
return $this->buildCredentialsQuery($credentials)
->firstOrFail()
->delete();
}
/**
* @param $key
* @param $value
* @return boolean
*/
public function deleteManyBy($key, $value) {
return $this->makeQuery()
->where($key, $value)
->take($this->limit)
->skip($this->offset)
->delete();
}
/**
* @param array $credentials
* @return boolean
*/
public function deleteManyByCredentials(array $credentials = []) {
return $this->buildCredentialsQuery($credentials)
->take($this->limit)
->skip($this->offset)
->delete();
}
/**
* @return mixed
*/
public function deleteMany() {
return $this->makeQuery()
->take($this->limit)
->delete();
}
/**
* @param array $ids
* @return mixed
*/
public function deleteManyByIds(array $ids) {
return $this->makeQuery()
->whereIn('id', $ids)
->delete();
}
/**
* @return bool|null
* @throws \Exception
*/
public function deleteAll() {
return $this->makeQuery()
->delete();
}
/**
* @param $credentials
* @return bool|null
* @throws \Exception
*/
public function deleteAllByCredentials($credentials) {
return $this->buildCredentialsQuery($credentials)
->delete();
}
/**
* @param array $credentials
* @param int $perPage
*
*
* samples :
* categories:in_relation:we|wed|wef|edf
* mobile:in:123|23|23|234
* name:=:majid
* age:<:20
* age:>:10
* family:like:%asghar%
*
* @return mixed
* @throws RepositoriesException
*/
public function searchByCredentials(array $credentials = [], $perPage = 10) {
$items = [];
foreach ($credentials as $key => $value) {
if (!is_array($value)) {
throw new RepositoriesException();
}
$items[] = ['key' => $key, 'operator' => $value[1], 'value' => $value[0]];
}
$result = $this->model;
foreach ($items as $item) {
if (count($relation = explode('.', $item['key'])) === 2) {
$result = $result->whereHas($relation[0], function ($query) use ($relation, $item) {
$query->where($relation[1], $item['operator'], $item['value']);
});
} elseif ($item['operator'] == 'in') {
$result = $result->whereIn($item['key'], explode('|', $item['value']));
} elseif ($item['operator'] == 'in_relation') {
$result = $result->whereHas($item['key'], function($q) use ($item) {
$q->whereIn(str_singular($item['key']) . '_id', explode('|', $item['value']));
});
} else {
$result = $result->Where($item['key'], $item['operator'], $item['value']);
}
}
return $result->with($this->with)->orderBy($this->orderBy, $this->sortMethod)->paginate($perPage, $this->columns);
}
/**
* @param array $data
* @return Model
*/
public function add(array $data) {
$item = $this->model;
foreach ($data as $k => $v)
$item->{$k} = $v;
if (array_key_exists('slug', $data))
$item->slug = slugify(array_key_exists('name', $data) ? $data['name'] : $data['title']);
$item->save();
return $item;
}
}
<?php
namespace Modules\Core\src\contracts;
use Illuminate\Support\Collection;
use Modules\Maintenance\src\generic\dtos\PaginationRequestDTO;
interface EloquentRepositoryInterface
{
public function filters(PaginationRequestDTO $pagination);
public function index(PaginationRequestDTO $requestDTO);
/**
*
* @return $this
*/
public function findFirst();
/**
* @param array $with
* @return $this
*/
public function with(array $with = []);
/**
* @param array $columns
* @return $this
*/
public function columns(array $columns = ['*']);
/**
* @param int $limit
* @return $this
*/
public function limit($limit = 10);
/**
* @param $orderBy
* @param string $sort
* @return $this
*/
public function orderBy($orderBy, $sort = 'DESC');
/**
* @param array $data
* @return mixed
*/
public function create();
/**
* @param array $data
* @return mixed
*/
public function findById($id);
/**
* @param array $data
* @return mixed
*/
public function store(array $data);
/**
* @param $id
* @return mixed
*/
public function findOneById($id);
/**
* @param $key
* @param $value
* @return mixed
*/
public function findOneBy($key, $value);
/**
* @param $key
* @param $value
* @return Collection
*/
public function findManyBy($key, $value);
/**
* @param array $ids
* @return mixed
*/
public function findManyByIds(array $ids);
/**
* @return Collection
*/
public function findAll();
/**
* @param array $credentials
* @return Collection
*/
public function findManyByCredentials(array $credentials = []);
/**
* @param $key
* @param $value
* @param int $perPage
* @return mixed
*/
public function paginateBy($key, $value, $perPage = 10);
/**
* @param int $perPage
* @return mixed
*/
public function paginate($perPage = 10);
/**
* @param $credentials
* @param int $perPage
* @return Paginator
*/
public function paginateByCredentials($credentials, $perPage = 10);
/**
* @param $id
* @param array $data
* @return boolean
*/
public function updateOneById($id, array $data = []);
/**
* @param $key
* @param $value
* @param array $data
* @return boolean
*/
public function updateOneBy($key, $value, array $data = []);
/**
* @param array $credentials
* @param array $data
* @return boolean
*/
public function updateOneByCredentials(array $credentials, array $data = []);
/**
* @param $key
* @param $value
* @param array $data
* @return boolean
*/
public function updateManyBy($key, $value, array $data = []);
/**
* @param array $credentials
* @param array $data
* @return boolean
*/
public function updateManyByCredentials(array $credentials = [], array $data = []);
/**
* @param array $ids
* @param array $data
* @return bool
*/
public function updateManyByIds(array $ids, array $data = []);
/**
* @param $id
* @return boolean
*/
public function deleteOneById($id);
/**
* @param array $ids
* @return bool
*/
public function allExist(array $ids);
/**
* @param $key
* @param $value
* @return boolean
*/
public function deleteOneBy($key, $value);
/**
* @param array $credentials
* @return boolean
*/
public function deleteOneByCredentials(array $credentials = []);
/**
* @param $key
* @param $value
* @return boolean
*/
public function deleteManyBy($key, $value);
/**
* @param array $credentials
* @return boolean
*/
public function deleteManyByCredentials(array $credentials = []);
/**
* @param array $credentials
* @param $perPage
*
* @return mixed
*/
public function searchByCredentials(array $credentials = [], $perPage);
public function deleteManyByIds(array $ids);
/**
* @param array $data
* @return mixed
*/
public function add(array $data);
/**
* @param $id
* @param $field
*/
public function inc($id, $field);
/**
* @param $id
* @param $field
*/
public function dec($id, $field);
}
<?php
namespace Modules\Maintenance\src\generic\dtos;
use Spatie\LaravelData\Data;
class PaginationRequestDTO extends Data
{
public function __construct(
public ?string $search,
public ?int $total,
public ?int $perPage = 10,
public ?int $current = 1,
public ?array $columns = ['*'],
public ?array $with = [],
public ?array $filters = [],
public ?array $searchable = []
){}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment