Skip to content

Instantly share code, notes, and snippets.

@KushalRaj
Last active August 7, 2019 11:40
Show Gist options
  • Save KushalRaj/38f2560da45866f3efa61d5119742401 to your computer and use it in GitHub Desktop.
Save KushalRaj/38f2560da45866f3efa61d5119742401 to your computer and use it in GitHub Desktop.
Apply filter functions dynamically as per parameters supplied.
<?php
namespace App\Criteria;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Str;
use Prettus\Repository\Contracts\CriteriaInterface;
use Prettus\Repository\Contracts\RepositoryInterface;
use Illuminate\Http\Request;
/**
* Class BaseCriteria
* @package App\Criteria
*/
abstract class BaseCriteria implements CriteriaInterface
{
/**
* @var array|Request|string
*/
protected $request;
/**
* @var Builder
*/
protected $builder;
/**
* QueryFilter constructor.
*
* @param array $request
*/
public function __construct(array $request = [])
{
$this->request = app()->runningInConsole() ? collect($request) : (empty($request) ? app('request') : collect($request));
}
/**
* Apply criteria in query repository
*
* @param Builder $model
* @param RepositoryInterface $repository
*
* @return mixed
*/
public function apply($model, RepositoryInterface $repository)
{
$this->builder = $model;
if ( method_exists($this, 'bootstrap') ) {
call_user_func([$this, 'bootstrap']);
}
foreach ( $this->filters() as $filter => $value ) {
if ( $this->isFilterApplicable($filter) ) {
$this->builder = call_user_func_array([$this, $this->getFilterMethodName($filter)], [$value]);
}
}
return $this->builder;
}
/**
* Get the filters from the request url
*
* @return array
*/
private function filters()
{
return $this->request->all();
}
/**
* Check if filter is applicable
*
* @param string $filter
*
* @return bool
*/
private function isFilterApplicable(string $filter): bool
{
return $this->hasMethodFor($filter) && !$this->isEmpty($this->request->get($filter));
}
/**
* Check if the class has method for provided filter
*
* @param string $filter
*
* @return bool
*/
private function hasMethodFor(string $filter): bool
{
return method_exists($this, $this->getFilterMethodName($filter));
}
/**
* Check if the search value is empty
*
* @param string|int|array $value
*
* @return bool
*/
private function isEmpty($value): bool
{
if ( is_array($value) ) {
return empty(array_filter($value));
}
return empty($value);
}
/**
* Get the name of the filter method
*
* @param string $filter
*
* @return string
*/
private function getFilterMethodName($filter)
{
return Str::camel($filter);
}
}
<?php
namespace App\Criteria;
use Illuminate\Database\Eloquent\Builder;
use App\Criteria\BaseCriteria;
/**
* Class PostCriteria
* @package App\Criteria
*/
class PostCriteria extends BaseCriteria
{
/**
* Executed before other filter functions
* Use for default sorting, joins, columns selection,
* global scopes, and more
*/
public function bootstrap()
{
$this->builder->getQuery()->orders = null;
}
/**
* @param string $name
*
* @return Builder
*/
public function name(string $name)
{
return $this->builder->where(
function ($query) use ($name) {
$query
->where('name', 'like', "$name%")
->orWhere('name', 'like', "% $name%");
}
);
}
/**
* @param string $status
*
* @return Builder
*/
public function status(string $status)
{
return $this->builder->where('status', $status);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment