diff --git a/src/Filters/QueryFilter.php b/src/Filters/QueryFilter.php index ae915e6..df66cef 100644 --- a/src/Filters/QueryFilter.php +++ b/src/Filters/QueryFilter.php @@ -2,75 +2,22 @@ namespace Oooiik\LaravelQueryFilter\Filters; -use http\Exception\BadMethodCallException; use Illuminate\Database\Eloquent\Builder; abstract class QueryFilter { /** @var Builder */ - protected $builder; - /** @var Builder */ - protected $realBuilder; + public $builder; /** * Here, default parameters for functions are saved * @var array */ - public array $default = []; + public $default = []; /** * Here, if a function does not work, a helper function is shown for it * @var array */ - public array $fallback = []; - - public function __construct(Builder $builder) - { - $this->realBuilder = $builder; - $this->builder = clone $this->realBuilder; - } - - public static function builder(Builder $builder) - { - return new static($builder); - } - - public function filters() - { - $staticClassMethods = get_class_methods(static::class); - $selfClassMethods = get_class_methods(self::class); - return array_diff($staticClassMethods, $selfClassMethods); - } - - public function apply(array $validated) - { - $validatedKeys = array_keys($validated); - $defaultKeys = array_keys($this->default); - $fallbackKeys = array_keys($this->fallback); - - foreach ($this->filters() as $filter) { - if (in_array($filter, $validatedKeys)) { - $this->$filter($validated[$filter], $validated); - } elseif (in_array($filter, $defaultKeys)) { - $this->$filter($this->default[$filter], $validated); - } elseif (in_array($filter, $fallbackKeys)) { - if(!in_array($this->fallback[$filter], $this->filters())){ - throw new \BadMethodCallException("This method not found!", 500); - } - $this->{$this->fallback[$filter]}(null, $validated); - } - } - return $this; - } - - public function resetApply(array $validated) - { - $this->builder = clone $this->realBuilder; - return $this->apply($validated); - } - - public function query() - { - return $this->builder; - } + public $fallback = []; } diff --git a/src/Services/FilterService.php b/src/Services/FilterService.php new file mode 100644 index 0000000..c36fc2b --- /dev/null +++ b/src/Services/FilterService.php @@ -0,0 +1,123 @@ +client = $client; + $this->baseBuilder = $builder; + $this->getClient()->builder = clone $this->baseBuilder; + } + + protected function getBaseBuilder() + { + return $this->baseBuilder; + } + + protected function getClient() + { + return $this->client; + } + + protected function getClientBuilder() + { + return $this->getClient()->builder; + } + + protected function getClientMethods() + { + return get_class_methods($this->getClient()); + } + + protected function getClientDefault(string $key = null) + { + if (empty($key)) { + return $this->getClient()->default ?? []; + } else { + return $this->getClientDefault()[$key] ?? null; + } + } + + protected function getClientFallback(string $key = null) + { + if ($key === null) { + return $this->getClient()->fallback ?? []; + } else { + return $this->getClientFallback()[$key] ?? null; + } + } + + public function query() + { + return $this->getClientBuilder(); + } + + protected function setParams($params) + { + $this->params = array_merge($this->getClientDefault(), $params); + } + + protected function getParam($key = null) + { + if ($key === null) { + return $this->params; + } else { + return $this->params[$key] ?? null; + } + } + + protected function callMethod($method) + { + if (!in_array($method, $this->getClientMethods())) { + throw new \BadMethodCallException("This method is not found in fallback!", 500); + } + call_user_func([$this->getClient(), $method], $this->getParam($method), $this->getParam()); + } + + protected function filterApply($method) + { + $paramsKeys = array_keys($this->getParam()); + $fallbackKeys = array_keys($this->getClientFallback()); + + if (in_array($method, $paramsKeys)) { + $this->callMethod($method); + } elseif (in_array($method, $fallbackKeys)) { + $this->callMethod($this->getClientFallback($method)); + } + } + + public function apply(array $params = []) + { + $this->setParams($params); + + foreach ($this->getClientMethods() as $method) { + $this->filterApply($method); + } + + return $this; + } + + public function resetApply() + { + $this->getClient()->builder = clone $this->getBaseBuilder(); + return $this; + } +} \ No newline at end of file diff --git a/src/Traits/Model/Filterable.php b/src/Traits/Model/Filterable.php index 8612fd5..d5ba5ae 100644 --- a/src/Traits/Model/Filterable.php +++ b/src/Traits/Model/Filterable.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Builder; use Oooiik\LaravelQueryFilter\Filters\QueryFilter; +use Oooiik\LaravelQueryFilter\Services\FilterService; use Symfony\Component\ErrorHandler\Error\ClassNotFoundError; /** @@ -14,7 +15,7 @@ trait Filterable { // protected $defaultFilter; - public function scopeFilter(Builder $query, array $validated = []) + public function scopeFilter(Builder $query, array $params = []) { if (!class_exists($this->defaultFilter)) { throw new ClassNotFoundError('Class not found', 500); @@ -22,12 +23,12 @@ public function scopeFilter(Builder $query, array $validated = []) if (!is_subclass_of($this->defaultFilter, QueryFilter::class)) { throw new ClassNotFoundError('It is not a successor class of Filter', 500); } - return $this->defaultFilter::builder($query)->apply($validated)->query(); + return (new FilterService( $this->defaultFilter, $query))->apply($params)->query(); } /** - * @param string $filter - * @return QueryFilter + * @param QueryFilter|string $filter + * @return FilterService */ public static function createFilter($filter) { @@ -38,6 +39,6 @@ public static function createFilter($filter) throw new ClassNotFoundError('It is not a successor class of Filter', 500); } $query = self::query(); - return $filter::builder($query); + return new FilterService($filter, $query); } }