Skip to content

Commit

Permalink
Filter definition. (#310)
Browse files Browse the repository at this point in the history
* Return repository key on filters.

* Apply fixes from StyleCI (#307)

* Adding filter definition.

* Apply fixes from StyleCI (#308)

* docs

* Map into qualified classes.

* Apply fixes from StyleCI (#309)

* wip
  • Loading branch information
binaryk authored Dec 16, 2020
1 parent 278984d commit 843e13f
Show file tree
Hide file tree
Showing 16 changed files with 509 additions and 185 deletions.
32 changes: 32 additions & 0 deletions docs/docs/4.0/search/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,38 @@ So now you can query this:
GET: /api/restify/users?is_active=true
```

### Match definition

You can implement a match filter definition, and specify for example related repository:

```php
public static $match = [
'title' => 'string',
'user_id' => MatchFilter::make()
->setType('int')
->setRelatedRepositoryKey(UserRepository::uriKey()),
];
```
When you will list this filter (with `posts/filters?only=matches`), you will get:

```json
{
"class": "Binaryk\LaravelRestify\Filters\MatchFilter"
"key": "matches"
"type": "string"
"column": "title"
"options": []
},
{
"class": "Binaryk\LaravelRestify\Filters\MatchFilter"
"key": "matches"
"type": "int"
"column": "user_id"
"options": []
"related_repository_key": "users"
"related_repository_url": "//users"
}
```
## Sort
When index query entities, usually we have to sort by specific attributes.

Expand Down
65 changes: 65 additions & 0 deletions src/Commands/FilterCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Binaryk\LaravelRestify\Commands;

use Illuminate\Console\ConfirmableTrait;
use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Str;

class FilterCommand extends GeneratorCommand
{
use ConfirmableTrait;

protected $name = 'restify:filter';

protected $description = 'Create a new filter class';

protected $type = 'Filter';

public function handle()
{
if (parent::handle() === false && ! $this->option('force')) {
return false;
}
}

/**
* Build the class with the given name.
* This method should return the file class content.
*
* @param string $name
* @return string
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
protected function buildClass($name)
{
if (false === Str::endsWith($name, 'Filter')) {
$name .= 'Filter';
}

return tap(parent::buildClass($name), function ($stub) use ($name) {
return str_replace(['{{ attribute }}', '{{ query }}'], Str::snake(
Str::beforeLast(class_basename($name), 'Filter')
), $stub);
});
}

protected function getStub()
{
return __DIR__.'/stubs/filter.stub';
}

protected function getPath($name)
{
if (false === Str::endsWith($name, 'Filter')) {
$name .= 'Filter';
}

return parent::getPath($name);
}

protected function getDefaultNamespace($rootNamespace)
{
return $rootNamespace.'\Restify\Matchers';
}
}
14 changes: 14 additions & 0 deletions src/Commands/stubs/filter.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace DummyNamespace;

use Binaryk\LaravelRestify\Filter;
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;

class DummyClass extends Filter
{
public function filter(RestifyRequest $request, $query, $value)
{
// $query->where('{{ attribute }}', $request->input('{{ query }}'));
}
}
76 changes: 68 additions & 8 deletions src/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Binaryk\LaravelRestify;

use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\Repositories\Repository;
use Binaryk\LaravelRestify\Traits\Make;
use Closure;
use Illuminate\Http\Request;
Expand All @@ -15,12 +16,18 @@ abstract class Filter implements JsonSerializable

public $type = 'value';

public $column;

public $value;

public $canSeeCallback;

public static $uriKey;

public $relatedRepositoryKey;

public Repository $repository;

public function __construct()
{
$this->booted();
Expand Down Expand Up @@ -55,6 +62,25 @@ protected function getType()
return $this->type;
}

public function getColumn(): ?string
{
return $this->column;
}

public function setColumn(string $column): self
{
$this->column = $column;

return $this;
}

public function setType(string $type): self
{
$this->type = $type;

return $this;
}

public function options(Request $request)
{
// noop
Expand All @@ -76,6 +102,36 @@ public function resolve(RestifyRequest $request, $filter)
$this->value = $filter;
}

public function getRelatedRepositoryKey(): ?string
{
return $this->relatedRepositoryKey;
}

public function setRelatedRepositoryKey(string $repositoryKey): self
{
$this->relatedRepositoryKey = $repositoryKey;

return $this;
}

public function setRepository(Repository $repository): self
{
$this->repository = $repository;

return $this;
}

public function getRelatedRepositoryUrl(): ?string
{
return ($key = $this->getRelatedRepositoryKey())
? with(Restify::repositoryForKey($key), function ($repository = null) {
if (is_subclass_of($repository, Repository::class)) {
return Restify::path($repository::uriKey());
}
})
: null;
}

/**
* Get the URI key for the filter.
*
Expand All @@ -87,24 +143,28 @@ public static function uriKey()
return static::$uriKey;
}

$kebabWithoutRepository = Str::kebab(Str::replaceLast('Filter', '', class_basename(get_called_class())));
$kebabWithoutFilter = Str::kebab(Str::replaceLast('Filter', '', class_basename(get_called_class())));

/**
* e.g. UserRepository => users
* e.g. LaravelEntityRepository => laravel-entities.
*/
return Str::plural($kebabWithoutRepository);
return Str::plural($kebabWithoutFilter);
}

public function jsonSerialize()
{
return [
return with([
'class' => static::class,
'key' => static::uriKey(),
'type' => $this->getType(),
'column' => $this->getColumn(),
'options' => collect($this->options(app(Request::class)))->map(function ($value, $key) {
return is_array($value) ? ($value + ['property' => $key]) : ['label' => $key, 'property' => $value];
})->values()->all(),
];
], function (array $initial) {
return $this->relatedRepositoryKey
? array_merge($initial, [
'related_repository_key' => $this->getRelatedRepositoryKey(),
'related_repository_url' => $this->getRelatedRepositoryUrl(),
])
: $initial;
});
}
}
49 changes: 49 additions & 0 deletions src/Filters/FilterDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Binaryk\LaravelRestify\Filters;

use Binaryk\LaravelRestify\Repositories\Repository;
use Binaryk\LaravelRestify\Restify;
use JsonSerializable;

abstract class FilterDefinition implements JsonSerializable
{
public static string $type = 'string';

public static string $relatedRepositoryKey;

public function getType(): string
{
return static::$type;
}

public function getRelatedRepositoryKey(): ?string
{
return static::$relatedRepositoryKey;
}

public function getRelatedRepositoryUrl(): ?string
{
return ($key = $this->getRelatedRepositoryKey())
? with(Restify::repositoryForKey($key), function ($repository = null) {
if (is_subclass_of($repository, Repository::class)) {
return Restify::path($repository::uriKey());
}
})
: null;
}

public function jsonSerialize()
{
return with([
'type' => $this->getType(),
], function (array $initial) {
return static::$relatedRepositoryKey
? array_merge($initial, [
'related_repository_key' => $this->getRelatedRepositoryKey(),
'related_repository_url' => $this->getRelatedRepositoryUrl(),
])
: $initial;
});
}
}
Loading

0 comments on commit 843e13f

Please sign in to comment.