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

ajsmith_codes's avatar

Need to combine two functions.

I have one web page that will perform these two functions: filter and sort

Right now they are separate functions because I followed two different tutorials. I need to combine them.

Function 1: Filter, located in the SearchController

  protected $customer;
    
    public function __construct(Customer $customer)
    {
        $this->customer = $customer;
    }
    
    public function filter(Request $request)
    {
        return CustomerResource::collection(
            CustomerSearch::apply($request)->paginate(10)
        );
    }

Function 2: Sort Columns, located in the APIController

        if (\request()->has('column')){

            $query = $this->customer->with('contacts', 'activeOrders')
                ->orderBy($request->column, $request->sortOrder);

            $customers = $query->paginate(10);

            return CustomerResource::collection($customers);

        } else {
            $customers = Customer::getAllCustomers();

            return response()->json($customers);
        }

CustomerResource:

    public function toArray($request)
    {
        return [
            'name' => $this->name,
            'number'=> $this->number,
            'activeOrders' => $this->activeOrders,
            'active' => $this->active,
            'slug' => $this->slug,
        ];
    }

Customer Search:

public static function apply(Request $filters)
    {

        return static::applyDecoratorsFromRequest($filters, (new Customer())->newQuery());
    }

    private static function applyDecoratorsFromRequest(Request $request, Builder $query)
    {

        if ($request->choose == 1) {
            $filterName = 'name';
            $value = $request->searchInput;

            $decorator = static::createFilterDecorator($filterName);

            if (static::isValidDecorator($decorator)) {
                $query = $decorator::apply($query, $value, $request);
            }
        }

        if ($request->choose == 2) {
            $filterName = 'active';
            $value = $request->active;

            $decorator = static::createFilterDecorator($filterName);

            if (static::isValidDecorator($decorator)) {
                $query = $decorator::apply($query, $value, $request);
            }
        }


        return $query;
    }

    private static function createFilterDecorator($name)
    {
        return __NAMESPACE__ . '\Filters\' . ucfirst($name);
    }

    private static function isValidDecorator($decorator)
    {
        return class_exists($decorator);
    }

    private static function getResults(Builder $query)
    {

        return $query->get();
    }
0 likes
6 replies
aurawindsurfing's avatar

@ajsmith_codes

This will not work for sure but this will be the general idea. Since your Customer Search returns a query you could apply further restrictions to it like so:

        private static function applyDecoratorsFromRequest(Request $request, Builder $query)
    {

        if ($request->choose == 1) {
            $filterName = 'name';
            $value = $request->searchInput;

            $decorator = static::createFilterDecorator($filterName);

            if (static::isValidDecorator($decorator)) {
                $query = $decorator::apply($query, $value, $request);
            }
        }

        if ($request->choose == 2) {
            $filterName = 'active';
            $value = $request->active;

            $decorator = static::createFilterDecorator($filterName);

            if (static::isValidDecorator($decorator)) {
                $query = $decorator::apply($query, $value, $request);
            }
        }


        return $query->with('contacts', 'activeOrders')
				->orderBy($request->column, $request->sortOrder);
    }

And therefore order it the way you like it.

Hope it helps!

Tray2's avatar

I don't understand the code since it's a bit of a mess, however make sure you do all your filtering and sorting in the database instead of in the collection fetched from the database.

It will be way faster and your application will use less memory.

1 like
Tray2's avatar

@aurawindsurfing No I mean using the database.

For example

$models = Model::where('field', $field)->orderBy('field', 'asc')->get();

Instead of doing something like this.

$models = Model::all();
$filteredModels = $models->filter(function ($value, $key) {
    return $value > 2;
});

$sortedModels = $filteredModels->sort();
2 likes
hanif-king's avatar

your code is not a proper better way for the filter and sorting. instead you could ask exactly what you want so others may guide you to better managed way .

ajsmith_codes's avatar

"your code is not a proper better way for the filter and sorting. instead you could ask exactly what you want so others may guide you to better managed way "

What I want is to be able to filter records and after those are filtered, be able to sort by column.

Please or to participate in this conversation.