Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
laravel-query-builder scope filter with model binding
<?php
namespace App\Http\Filters;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use ReflectionObject;
use Spatie\QueryBuilder\Filters\Filter;
class ScopeFilter implements Filter
{
public function __invoke(Builder $query, $values, string $property): Builder
{
$scope = Str::camel($property);
$values = Arr::wrap($values);
$values = $this->replaceValuesWithModels($query, $scope, $values);
return $query->$scope(...$values);
}
protected function replaceValuesWithModels(Builder $query, string $scope, array $values): array
{
$scopeParameters = (new ReflectionObject($query->getModel()))
->getMethod('scope' . ucfirst($scope))
->getParameters();
foreach ($scopeParameters as $scopeParameter) {
if (! $scopeParameter->getClass()->isSubclassOf(Model::class)) {
continue;
}
$model = $scopeParameter->getClass()->newInstance();
$index = $scopeParameter->getPosition() - 1;
$value = $values[$index];
if (is_numeric($value)) {
$values[$index] = $model::find($value);
}
}
return $values;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment