Skip to content

Commit

Permalink
Individual array delimiter for a single filter #450 (#451)
Browse files Browse the repository at this point in the history
* Gitignore IntelliJ Workspace

* Individual array delimiter for a single filter #450

* Add tests + set delimiter arg as optional #450

* Fix style CI

* Fix style CI

* Fix style CI
  • Loading branch information
btxtiger authored Aug 18, 2020
1 parent 29bda13 commit 47b1a58
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ vendor
.php_cs.cache
coverage
.phpunit.result.cache
/.idea
15 changes: 15 additions & 0 deletions docs/advanced-usage/multi-value-delimiter.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,18 @@ public function handle($request, $next) {
return $next($request);
}
```

You can also set the delimiter for each feature individually:
```php
QueryBuilderRequest::setIncludesArrayValueDelimiter(';'); // Includes
QueryBuilderRequest::setAppendsArrayValueDelimiter(';'); // Appends
QueryBuilderRequest::setFieldsArrayValueDelimiter(';'); // Fields
QueryBuilderRequest::setSortsArrayValueDelimiter(';'); // Sorts
QueryBuilderRequest::setFilterArrayValueDelimiter(';'); // Filter
```

You can override the default delimiter for single filters:
```php
// GET /api/endpoint?filter[id]=h4S4MG3(+>azv4z/I<o>,>XZII/Q1On
AllowedFilter::exact('id', 'ref_id', true, ';');
```
37 changes: 24 additions & 13 deletions src/AllowedFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,29 +49,38 @@ public function filter(QueryBuilder $query, $value)
($this->filterClass)($query->getEloquentBuilder(), $valueToFilter, $this->internalName);
}

public static function exact(
string $name,
?string $internalName = null,
bool $addRelationConstraint = true
): self {
public static function setFilterArrayValueDelimiter(string $delimiter = null): void
{
if (isset($delimiter)) {
QueryBuilderRequest::setFilterArrayValueDelimiter($delimiter);
}
}

public static function exact(string $name, ?string $internalName = null, bool $addRelationConstraint = true, string $arrayValueDelimiter = null): self
{
static::setFilterArrayValueDelimiter($arrayValueDelimiter);

return new static($name, new FiltersExact($addRelationConstraint), $internalName);
}

public static function partial(
string $name,
$internalName = null,
bool $addRelationConstraint = true
): self {
public static function partial(string $name, $internalName = null, bool $addRelationConstraint = true, string $arrayValueDelimiter = null): self
{
static::setFilterArrayValueDelimiter($arrayValueDelimiter);

return new static($name, new FiltersPartial($addRelationConstraint), $internalName);
}

public static function scope(string $name, $internalName = null): self
public static function scope(string $name, $internalName = null, string $arrayValueDelimiter = null): self
{
static::setFilterArrayValueDelimiter($arrayValueDelimiter);

return new static($name, new FiltersScope(), $internalName);
}

public static function callback(string $name, $callback, $internalName = null): self
public static function callback(string $name, $callback, $internalName = null, string $arrayValueDelimiter = null): self
{
static::setFilterArrayValueDelimiter($arrayValueDelimiter);

return new static($name, new FiltersCallback($callback), $internalName);
}

Expand All @@ -80,8 +89,10 @@ public static function trashed(string $name = 'trashed', $internalName = null):
return new static($name, new FiltersTrashed(), $internalName);
}

public static function custom(string $name, Filter $filterClass, $internalName = null): self
public static function custom(string $name, Filter $filterClass, $internalName = null, string $arrayValueDelimiter = null): self
{
static::setFilterArrayValueDelimiter($arrayValueDelimiter);

return new static($name, $filterClass, $internalName);
}

Expand Down
113 changes: 83 additions & 30 deletions src/QueryBuilderRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@

class QueryBuilderRequest extends Request
{
private static $arrayValueDelimiter = ',';
private static $includesArrayValueDelimiter = ',';
private static $appendsArrayValueDelimiter = ',';
private static $fieldsArrayValueDelimiter = ',';
private static $sortsArrayValueDelimiter = ',';
private static $filterArrayValueDelimiter = ',';

public static function setArrayValueDelimiter(string $delimiter): void
{
static::$arrayValueDelimiter = $delimiter;
}

public static function getArrayValueDelimiter(): string
{
return static::$arrayValueDelimiter;
static::$filterArrayValueDelimiter = $delimiter;
static::$includesArrayValueDelimiter = $delimiter;
static::$appendsArrayValueDelimiter = $delimiter;
static::$fieldsArrayValueDelimiter = $delimiter;
static::$sortsArrayValueDelimiter = $delimiter;
}

public static function fromRequest(Request $request): self
Expand All @@ -32,7 +35,7 @@ public function includes(): Collection
$includeParts = $this->query($includeParameterName);

if (! is_array($includeParts)) {
$includeParts = explode(static::getArrayValueDelimiter(), $this->query($includeParameterName));
$includeParts = explode(static::getIncludesArrayValueDelimiter(), $this->query($includeParameterName));
}

return collect($includeParts)
Expand All @@ -47,29 +50,12 @@ public function appends(): Collection
$appendParts = $this->query($appendParameterName);

if (! is_array($appendParts)) {
$appendParts = explode(static::getArrayValueDelimiter(), strtolower($appendParts));
$appendParts = explode(static::getAppendsArrayValueDelimiter(), strtolower($appendParts));
}

return collect($appendParts)->filter();
}

public function filters(): Collection
{
$filterParameterName = config('query-builder.parameters.filter');

$filterParts = $this->query($filterParameterName, []);

if (is_string($filterParts)) {
return collect();
}

$filters = collect($filterParts);

return $filters->map(function ($value) {
return $this->getFilterValue($value);
});
}

public function fields(): Collection
{
$fieldsParameterName = config('query-builder.parameters.fields');
Expand All @@ -81,7 +67,7 @@ public function fields(): Collection
}

return $fieldsPerTable->map(function ($fields) {
return explode(static::getArrayValueDelimiter(), $fields);
return explode(static::getFieldsArrayValueDelimiter(), $fields);
});
}

Expand All @@ -92,12 +78,29 @@ public function sorts(): Collection
$sortParts = $this->query($sortParameterName);

if (is_string($sortParts)) {
$sortParts = explode(static::getArrayValueDelimiter(), $sortParts);
$sortParts = explode(static::getSortsArrayValueDelimiter(), $sortParts);
}

return collect($sortParts)->filter();
}

public function filters(): Collection
{
$filterParameterName = config('query-builder.parameters.filter');

$filterParts = $this->query($filterParameterName, []);

if (is_string($filterParts)) {
return collect();
}

$filters = collect($filterParts);

return $filters->map(function ($value) {
return $this->getFilterValue($value);
});
}

/**
* @param $value
*
Expand All @@ -111,8 +114,8 @@ protected function getFilterValue($value)
})->all();
}

if (Str::contains($value, static::getArrayValueDelimiter())) {
return explode(static::getArrayValueDelimiter(), $value);
if (Str::contains($value, static::getFilterArrayValueDelimiter())) {
return explode(static::getFilterArrayValueDelimiter(), $value);
}

if ($value === 'true') {
Expand All @@ -125,4 +128,54 @@ protected function getFilterValue($value)

return $value;
}

public static function setIncludesArrayValueDelimiter(string $includesArrayValueDelimiter): void
{
static::$includesArrayValueDelimiter = $includesArrayValueDelimiter;
}

public static function setAppendsArrayValueDelimiter(string $appendsArrayValueDelimiter): void
{
static::$appendsArrayValueDelimiter = $appendsArrayValueDelimiter;
}

public static function setFieldsArrayValueDelimiter(string $fieldsArrayValueDelimiter): void
{
static::$fieldsArrayValueDelimiter = $fieldsArrayValueDelimiter;
}

public static function setSortsArrayValueDelimiter(string $sortsArrayValueDelimiter): void
{
static::$sortsArrayValueDelimiter = $sortsArrayValueDelimiter;
}

public static function setFilterArrayValueDelimiter(string $filterArrayValueDelimiter): void
{
static::$filterArrayValueDelimiter = $filterArrayValueDelimiter;
}

public static function getIncludesArrayValueDelimiter(): string
{
return static::$includesArrayValueDelimiter;
}

public static function getAppendsArrayValueDelimiter(): string
{
return static::$appendsArrayValueDelimiter;
}

public static function getFieldsArrayValueDelimiter(): string
{
return static::$fieldsArrayValueDelimiter;
}

public static function getSortsArrayValueDelimiter(): string
{
return static::$sortsArrayValueDelimiter;
}

public static function getFilterArrayValueDelimiter(): string
{
return static::$filterArrayValueDelimiter;
}
}
34 changes: 34 additions & 0 deletions tests/FilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,4 +510,38 @@ protected function createQueryFromFilterRequest(array $filters): QueryBuilder

return QueryBuilder::for(TestModel::class, $request);
}

/** @test */
public function it_can_override_the_array_value_delimiter_for_single_filters()
{
TestModel::create(['name' => '>XZII/Q1On']);
TestModel::create(['name' => 'h4S4MG3(+>azv4z/I<o>']);

// First use default delimiter
$models = $this
->createQueryFromFilterRequest([
'ref_id' => 'h4S4MG3(+>azv4z/I<o>,>XZII/Q1On',
])
->allowedFilters(AllowedFilter::exact('ref_id', 'name', true))
->get();
$this->assertEquals(2, $models->count());

// Custom delimiter
$models = $this
->createQueryFromFilterRequest([
'ref_id' => 'h4S4MG3(+>azv4z/I<o>|>XZII/Q1On',
])
->allowedFilters(AllowedFilter::exact('ref_id', 'name', true, '|'))
->get();
$this->assertEquals(2, $models->count());

// Custom delimiter, but default in request
$models = $this
->createQueryFromFilterRequest([
'ref_id' => 'h4S4MG3(+>azv4z/I<o>,>XZII/Q1On',
])
->allowedFilters(AllowedFilter::exact('ref_id', 'name', true, '|'))
->get();
$this->assertEquals(0, $models->count());
}
}

0 comments on commit 47b1a58

Please sign in to comment.