Laravel - searching by multiple tags and a string

392 Views Asked by At

In my Laravel app I have a search function, in said search function the user can search by a query string and a selection of tags.

An ordinary search query would produce a request like the following:

https://events-portal.test/api/events/search?q=search where q is the query string.

I also have a series of tags that users can select many of, then the request looks like the following:

https://events-portal.test/api/events/search?q=search&tags[]=%7B%22slug%22:%22business-development%22%7D

However, this feels broken as when I paginate Laravel only brings the query string to the next page.

Should I really be passing the entire object to the query string?

Essentially, is there a better way to pass multiple of the same parameter to the query string instead of an object as an array?

Code


    public function search(Request $request)
    {
        $search_term = $request->get('q');
        $tags = $request->get('tags');

        // Organise tags from request into usable array
        $tags = collect($tags)->map(function ($item, $key) {
            return [
                json_decode($item)->slug,
            ];
        })->flatten()->toArray();

        // Build error message if no results are found
        $error = ['error' => "No results found for '{$request->get('q')}'"];

        $error['error'] = count($tags) > 0
            ? $error['error'] . ' with ' . count($tags) . ' tag(s) selected.'
            : $error['error'];

        // If there is a search term, search for events meeting search criteria
        if (!empty($search_term)) {
            $events = Event::search($search_term)->query(function ($query) use ($tags) {
                return $query->listed()
                    ->when(count($tags) > 0, function ($query) use ($tags) {
                        return $query->withTag($tags);
                    })
                    ->select('id', 'title', 'header_image_url', 'location', 'start_datetime', 'finish_datetime');
            })->paginate(6);
        }
        // If there is NO search term, load all listed events meeting tag criteria
        else {
            $events = Event::listed()
                ->withTag($tags)
                ->select('id', 'title', 'header_image_url', 'location', 'start_datetime', 'finish_datetime')
                ->orderBy('start_datetime')
                ->paginate(6);
        }

        return $events->count() ? $events : $error;
    }

0

There are 0 best solutions below