Tucker-Eric/EloquentFilter

Status if result is filtered

pahy opened this issue · 4 comments

pahy commented

Is there a way to find out if any of the modelfilter functions was triggered? Or the result is filtered at least?
Thanks in advance.

All the input used to filter a model is stored in a protected $filtered array on the initial model so you'd be able to access it through the builder like:

// On your model
class MyModel extends Model
{
    use Filterable;
    //Model logic
    public function getFilterInput()
    {
        return $this->filtered;
    }
}

// Where your query is.
$builder = MyModel::filter($request->all());
$filteredInput = $builder->getModel()->getFilterInput();
$result = $builder->get();
pahy commented

Please let me explain my requirement in more detail.
The $filtered is fine, but contains everything included in my search query. And the filtermodel-functions might only affect a subset of the given filters from the input.
The user queries something like
filter[lastname]=Doe&filter[doesnotexist]=anything
There is a filtermodel-function for 'lastname', but not for 'doesnotexist'.
Is there a way to get a automated list/array, which filtermodel-function was triggered? Something containing the filter for 'lastname', but none for 'doesnotexist', because there is no filtermodel-function for "doesnotexist"?
The result could look like

[
  "lastname" => ["Doe"]
]

or in a luxurious finish anything in the way like

[
  "ModelFilter::lastname"=>["Doe"]
]

Ahhh, I see.

I'd recommend doing it in a setup method that gets called, if present on a model filter, initially regardless of input. Then creating a setter on your model to set the filtered input (since that property is protected).

public function setup()
{
    $filtered = [];
    foreach ($this->input as $key => $val) {        
        if ($this->methodIsCallable($method = $this->getFilterMethod($key))) {
            $filtered[static::class . '::' . $method] = $val;
        }
    }

    $this->query->getModel()->setFiltered($filtered);
}

You could even extend the Filterable trait and add the setter to that to avoid creating a setter for every model that you want to track the filtered input.

Or you could extend the ModelFilter class and put this logic there with an accessible variable to store the filtered input across instances.

pahy commented

Thank you. Flawless!