Skip to content

Commit

Permalink
update structure
Browse files Browse the repository at this point in the history
  • Loading branch information
oooiik committed Nov 8, 2022
1 parent 9ba908b commit 014b75e
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 61 deletions.
59 changes: 3 additions & 56 deletions src/Filters/QueryFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
}
123 changes: 123 additions & 0 deletions src/Services/FilterService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php

namespace Oooiik\LaravelQueryFilter\Services;

use Illuminate\Database\Eloquent\Builder;
use Oooiik\LaravelQueryFilter\Filters\QueryFilter;

class FilterService
{
protected $client;

protected $baseBuilder;

protected $params = [];

/**
* @param QueryFilter|string $client
* @param Builder $builder
*/
public function __construct($client, Builder $builder)
{
if(is_string($client)){
$client = new $client();
}
$this->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;
}
}
11 changes: 6 additions & 5 deletions src/Traits/Model/Filterable.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -14,20 +15,20 @@ 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);
}
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)
{
Expand All @@ -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);
}
}

0 comments on commit 014b75e

Please sign in to comment.