Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

AleAnto's avatar

Dynamic Filters: Controller Logic or Component Responsibility?

Hi everyone, I'm evaluating an architectural decision in my Laravel 12 project.

I have a page that displays filters configurable on three levels:

  • from config file: full list of available filters
  • from DB per company: each company decides which filters to use and in what order
  • from DB per user: each user enables/disables/moves filters via the UI

The ModuleConfigService generates the final $filters array.

Solution 1 (Controller): The controller uses the service to get $filters and $options, and passes them to the view:

Solution 2 (Component): The controller only passes $options. The component gets the module from the route and uses the service to retrieve $filters.

Advantages of Solution 2: less boilerplate, centralized logic in the component. Concerns: risk of making the component too coupled and harder to test.

In reality, the same logic is repeated for other arrays (fields, tabs, etc.), so I’d like to avoid duplication in controllers.

How do you handle this kind of situation? Do you prefer passing everything from the controller or delegating to the component?

Thanks!

0 likes
2 replies
Glukinho's avatar

centralized logic in the component

How is it better than centralized logic in controller? In model? In service?

The logic has to be put somewhere, after all.

My suggestion is to do as you prefer, after you make sure your decision was wrong, you refactor other way.

martinbean's avatar

@aleanto “Filters” are usually query string parameters (?filter[color]=red, ?filter[size]=small, etc). If these come from different data sources (e.g. hard-coded, user preferences) then I’d maybe create some sort of “filter collection“ object that you can then register filters with, and then they’re presenting in your UI. Your controller can then take care of fetching the filters from there various sources, and assembling your full filter collection:

public function index()
{
    // Get company filters from where ever...
    // Get user filters from where ever...

    $filters = FilterCollection::standardFilters()->merge([
        $companyFilters,
        $userFilters,
    ]);

    return view('resource.index')->with([
        'filters' => $filters,
    ]);
}

Please or to participate in this conversation.