Skip to content

Instantly share code, notes, and snippets.

@jalallinux
Created May 27, 2024 06:04
Show Gist options
  • Save jalallinux/3fdf8d4cdcd1325c0517bececd5c667d to your computer and use it in GitHub Desktop.
Save jalallinux/3fdf8d4cdcd1325c0517bececd5c667d to your computer and use it in GitHub Desktop.
ApiRequestCriteria [andersao/l5-repository](https://github.com/andersao/l5-repository)
<?php
namespace App\Contracts;
use Illuminate\Database\Eloquent\Builder;
use Prettus\Repository\Contracts\RepositoryInterface;
use Prettus\Repository\Criteria\RequestCriteria;
class ApiRequestCriteria extends RequestCriteria
{
public function apply($model, RepositoryInterface $repository)
{
$fieldsSearchable = $repository->getFieldsSearchable();
$search = $this->request->query(config('repository.criteria.params.search', 'search'), null);
$searchFields = $this->request->query(config('repository.criteria.params.searchFields', 'searchFields'), null);
$filter = $this->request->query(config('repository.criteria.params.filter', 'filter'), null);
$orderBy = $this->request->query(config('repository.criteria.params.orderBy', 'orderBy'), 'created_at');
$sortedBy = $this->request->query(config('repository.criteria.params.sortedBy', 'sortedBy'), 'desc');
$with = $this->request->query(config('repository.criteria.params.with', 'with'), null);
$withCount = $this->request->query(config('repository.criteria.params.withCount', 'withCount'), null);
$searchJoin = $this->request->query(config('repository.criteria.params.searchJoin', 'searchJoin'), '');
$scopes = $this->request->query(config('repository.criteria.params.scopes', 'scopes'), null);
if ($search && is_array($fieldsSearchable) && count($fieldsSearchable)) {
$searchFields = is_array($searchFields) || is_null($searchFields) ? $searchFields : array_filter(explode(';', $searchFields));
$isFirstField = true;
$searchData = $this->parserSearchData($search);
$fields = $this->parserFieldsSearch($fieldsSearchable, $searchFields, array_keys($searchData));
$search = $this->parserSearchValue($search);
$modelForceAndWhere = strtolower($searchJoin) === 'and';
$model = $model->where(function ($query) use ($fields, $search, $searchData, $isFirstField, $modelForceAndWhere) {
/** @var Builder $query */
foreach ($fields as $field => $condition) {
if (is_numeric($field)) {
$field = $condition;
$condition = '=';
}
$value = null;
$condition = trim(strtolower($condition));
if (isset($searchData[$field])) {
$value = ($condition == 'like' || $condition == 'ilike') ? "%{$searchData[$field]}%" : $searchData[$field];
} else {
if (! is_null($search) && ! in_array($condition, ['in', 'between'])) {
$value = ($condition == 'like' || $condition == 'ilike') ? "%{$search}%" : $search;
}
}
$relation = null;
if (stripos($field, '.')) {
$explode = array_filter(explode('.', $field));
$field = array_pop($explode);
$relation = implode('.', $explode);
}
if ($condition === 'in') {
$value = array_filter(explode(',', $value));
if (trim($value[0]) === '' || $field == $value[0]) {
$value = null;
}
}
if ($condition === 'between') {
$value = array_filter(explode(',', $value));
if (count($value) < 2) {
$value = null;
}
}
if (in_array($condition, ['null', 'not_null'])) {
$value = '';
}
$modelTableName = $query->getModel()->getTable();
if ($isFirstField || $modelForceAndWhere) {
if (! is_null($value)) {
if (! is_null($relation)) {
$query->whereHas($relation, function ($query) use ($field, $condition, $value) {
if ($condition === 'in') {
$query->whereIn($field, $value);
} elseif ($condition === 'between') {
$query->whereBetween($field, $value);
} elseif ($condition === 'null') {
$query->whereNull($field);
} elseif ($condition === 'not_null') {
$query->whereNotNull($field);
} else {
$query->where($field, $condition, $value);
}
});
} else {
if ($condition === 'in') {
$query->whereIn($modelTableName.'.'.$field, $value);
} elseif ($condition === 'between') {
$query->whereBetween($modelTableName.'.'.$field, $value);
} elseif ($condition === 'null') {
$query->whereNull($modelTableName.'.'.$field);
} elseif ($condition === 'not_null') {
$query->whereNotNull($modelTableName.'.'.$field);
} else {
$query->where($modelTableName.'.'.$field, $condition, $value);
}
}
$isFirstField = false;
}
} else {
if (! is_null($value)) {
if (! is_null($relation)) {
$query->orWhereHas($relation, function ($query) use ($field, $condition, $value) {
if ($condition === 'in') {
$query->whereIn($field, $value);
} elseif ($condition === 'between') {
$query->whereBetween($field, $value);
} elseif ($condition === 'null') {
$query->whereNull($field);
} elseif ($condition === 'not_null') {
$query->whereNotNull($field);
} else {
$query->where($field, $condition, $value);
}
});
} else {
if ($condition === 'in') {
$query->orWhereIn($modelTableName.'.'.$field, $value);
} elseif ($condition === 'between') {
$query->whereBetween($modelTableName.'.'.$field, $value);
} elseif ($condition === 'null') {
$query->whereNull($modelTableName.'.'.$field);
} elseif ($condition === 'not_null') {
$query->whereNotNull($modelTableName.'.'.$field);
} else {
$query->orWhere($modelTableName.'.'.$field, $condition, $value);
}
}
}
}
}
});
}
if (isset($orderBy) && ! empty($orderBy)) {
$orderBySplit = array_filter(explode(';', $orderBy));
if (count($orderBySplit) > 1) {
$sortedBySplit = array_filter(explode(';', $sortedBy));
foreach ($orderBySplit as $orderBySplitItemKey => $orderBySplitItem) {
$sortedBy = isset($sortedBySplit[$orderBySplitItemKey]) ? $sortedBySplit[$orderBySplitItemKey] : $sortedBySplit[0];
$model = $this->parserFieldsOrderBy($model, $orderBySplitItem, $sortedBy);
}
} else {
$model = $this->parserFieldsOrderBy($model, $orderBySplit[0], $sortedBy);
}
}
if (isset($filter) && ! empty($filter)) {
if (is_string($filter)) {
$filter = array_filter(explode(';', $filter));
}
$model = $model->select($filter);
}
if ($with) {
$with = array_filter(explode(';', $with));
$model = $model->with($with);
}
if ($withCount) {
$withCount = array_filter(explode(';', $withCount));
$model = $model->withCount($withCount);
}
if ($scopes) {
$scopes = array_filter(explode(';', $scopes));
$model = $model->scopes($scopes);
}
return $model;
}
}
<?php
/*
|--------------------------------------------------------------------------
| Prettus Repository Config
|--------------------------------------------------------------------------
|
|
*/
return [
/*
|--------------------------------------------------------------------------
| Repository Pagination Limit Default
|--------------------------------------------------------------------------
|
*/
'pagination' => [
'limit' => 15,
],
/*
|--------------------------------------------------------------------------
| Fractal Presenter Config
|--------------------------------------------------------------------------
|
Available serializers:
ArraySerializer
DataArraySerializer
JsonApiSerializer
*/
'fractal' => [
'params' => [
'include' => 'include',
],
'serializer' => League\Fractal\Serializer\DataArraySerializer::class,
],
/*
|--------------------------------------------------------------------------
| Cache Config
|--------------------------------------------------------------------------
|
*/
'cache' => [
/*
|--------------------------------------------------------------------------
| Cache Status
|--------------------------------------------------------------------------
|
| Enable or disable cache
|
*/
'enabled' => false,
/*
|--------------------------------------------------------------------------
| Cache Minutes
|--------------------------------------------------------------------------
|
| Time of expiration cache
|
*/
'minutes' => 30,
/*
|--------------------------------------------------------------------------
| Cache Repository
|--------------------------------------------------------------------------
|
| Instance of Illuminate\Contracts\Cache\Repository
|
*/
'repository' => 'cache',
/*
|--------------------------------------------------------------------------
| Cache Clean Listener
|--------------------------------------------------------------------------
|
|
|
*/
'clean' => [
/*
|--------------------------------------------------------------------------
| Enable clear cache on repository changes
|--------------------------------------------------------------------------
|
*/
'enabled' => true,
/*
|--------------------------------------------------------------------------
| Actions in Repository
|--------------------------------------------------------------------------
|
| create : Clear Cache on create Entry in repository
| update : Clear Cache on update Entry in repository
| delete : Clear Cache on delete Entry in repository
|
*/
'on' => [
'create' => true,
'update' => true,
'delete' => true,
],
],
'params' => [
/*
|--------------------------------------------------------------------------
| Skip Cache Params
|--------------------------------------------------------------------------
|
|
| Ex: http://prettus.local/?search=lorem&skipCache=true
|
*/
'skipCache' => 'skipCache',
],
/*
|--------------------------------------------------------------------------
| Methods Allowed
|--------------------------------------------------------------------------
|
| methods cacheable : all, paginate, find, findByField, findWhere, getByCriteria
|
| Ex:
|
| 'only' =>['all','paginate'],
|
| or
|
| 'except' =>['find'],
*/
'allowed' => [
'only' => null,
'except' => null,
],
],
/*
|--------------------------------------------------------------------------
| Criteria Config
|--------------------------------------------------------------------------
|
| Settings of request parameters names that will be used by Criteria
|
*/
'criteria' => [
/*
|--------------------------------------------------------------------------
| Accepted Conditions
|--------------------------------------------------------------------------
|
| Conditions accepted in consultations where the Criteria
|
| Ex:
|
| 'acceptedConditions'=>['=','like']
|
| $query->where('foo','=','bar')
| $query->where('foo','like','bar')
|
*/
'acceptedConditions' => [
'>=',
'<=',
'>',
'<',
'=',
'like',
'in',
'between',
'null',
'not_null',
],
/*
|--------------------------------------------------------------------------
| Request Params
|--------------------------------------------------------------------------
|
| Request parameters that will be used to filter the query in the repository
|
| Params :
|
| - search : Searched value
| Ex: http://prettus.local/?search=lorem
|
| - searchFields : Fields in which research should be carried out
| Ex:
| http://prettus.local/?search=lorem&searchFields=name;email
| http://prettus.local/?search=lorem&searchFields=name:like;email
| http://prettus.local/?search=lorem&searchFields=name:like
|
| - filter : Fields that must be returned to the response object
| Ex:
| http://prettus.local/?search=lorem&filter=id,name
|
| - orderBy : Order By
| Ex:
| http://prettus.local/?search=lorem&orderBy=id
|
| - sortedBy : Sort
| Ex:
| http://prettus.local/?search=lorem&orderBy=id&sortedBy=asc
| http://prettus.local/?search=lorem&orderBy=id&sortedBy=desc
|
| - searchJoin: Specifies the search method (AND / OR), by default the
| application searches each parameter with OR
| EX:
| http://prettus.local/?search=lorem&searchJoin=and
| http://prettus.local/?search=lorem&searchJoin=or
|
*/
'params' => [
'search' => 'search',
'searchFields' => 'searchFields',
'filter' => 'filter',
'orderBy' => 'orderBy',
'sortedBy' => 'sortedBy',
'with' => 'with',
'searchJoin' => 'searchJoin',
'withCount' => 'withCount',
'scopes' => 'scopes',
],
],
/*
|--------------------------------------------------------------------------
| Generator Config
|--------------------------------------------------------------------------
|
*/
'generator' => [
'basePath' => app()->path(),
'rootNamespace' => 'App\\',
'stubsOverridePath' => app()->path(),
'paths' => [
'models' => 'Models',
'repositories' => 'Repositories',
'interfaces' => 'Repositories',
'transformers' => 'Http\Resource',
'presenters' => 'Presenters',
'validators' => 'Validators',
'controllers' => 'Http/Controllers',
'provider' => 'RepositoryServiceProvider',
'criteria' => 'Criteria',
],
],
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment