PHPackages                             petrelli/search-interface-builder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. petrelli/search-interface-builder

ActiveLibrary[Search &amp; Filtering](/categories/search)

petrelli/search-interface-builder
=================================

Build and manage search categories and links easily, including all url's and their respective states

v0.0.5-alpha(6y ago)12.5k1MITPHPPHP ^7.0CI failing

Since Jul 1Pushed 6y agoCompare

[ Source](https://github.com/ferpetrelli/search-filters-builder)[ Packagist](https://packagist.org/packages/petrelli/search-interface-builder)[ RSS](/packages/petrelli-search-interface-builder/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (4)Dependencies (1)Versions (5)Used By (0)

Search Interface Builder
========================

[](#search-interface-builder)

Build and maintain filters for your listings.

Everything will be automatically managed. URL's, Values, Labels, etc. by just defining a few classes.

Live Example
============

[](#live-example)

Please [visit here](https://fernandopetrelli.com/filters) and click around.

The complete view for this example is a just few lines:

```
@foreach ($filtering->filters() as $filter)

        {{ $filter->label() }}
        @foreach($filter->links() as $option)
            active) class="active" @endif>
                {{ $option->label }}

        @endforeach

@endforeach

@if ($filtering->activeFilters()->isNotEmpty())

        Selected filters:
        @foreach($filtering->activeFilters() as $option)
            {{ $option->label }}
        @endforeach
        Clear all

@endif
```

The entire logic to build all URL's is managed automatically by our Sections and Filters classes.

Performing an actual search
===========================

[](#performing-an-actual-search)

The way an actual search is triggered on your data sources is entirely up to you.

This package will provide you with a simple and flexible way to build your filters and sorters, but connecting the generated URL's will depend on your application.

Executing scopes
----------------

[](#executing-scopes)

To close this gap, I recommend using the [Scoped Controller](https://github.com/ferpetrelli/scoped-controller) package.

It's solely functionality is to execute scopes over your query builders depending on your URL's, which makes it a perfect fit.

Your controllers and views will always be decluttered this way.

Installation
============

[](#installation)

Include it in your composer.json file calling

```
composer require petrelli/search-interface-builder

```

Or add:

```
"petrelli/search-interface-builder": "^0.0.2@alpha"

```

And run `composer update`.

Service provider
----------------

[](#service-provider)

Only if you have disabled Laravel's auto-discover, you'll have to manually add the service provider to your `config/app.php` file.

```
'providers' => [
    //...
    Petrelli\SearchInterfaceBuilder\ServiceProvider::class,
    //...
]
```

Important Concepts
==================

[](#important-concepts)

Section
-------

[](#section)

A section is a collection of filters and/or a sorter. You can define as many sections as you want.

[![A section](/docs/images/bar.png "Section")](/docs/images/bar.png)

Filter
------

[](#filter)

A Filter is a specific category to filter your collection (for example, Department and Location on the previous image).

You can reutilize filters across your sections.

Directory structure
===================

[](#directory-structure)

By default everything will be located under `App/Filters`.

- `App/Filters/Definitions`: Filters classes and sorters (Location, Year, ByPrice, etc.).
- `App/Filters/Sections`: Main search, staff search, events search, etc.

Usage
=====

[](#usage)

1. Create a new empty Section.
------------------------------

[](#1-create-a-new-empty-section)

```
php artisan search-builder:section [name] [route.name?]

```

This will generate a new Section class inside `App\Filters\Sections`.

If you don't specify a route please open the generated file and update it.

2.1 Create Filters
------------------

[](#21-create-filters)

```
php artisan search-builder:filter [name]

```

This will generate a new Filter class inside `App\Filters\Definitions`.

```
namespace App\Filters\Definitions;

class Location extends Petrelli\SearchInterfaceBuilder\MultipleSelector
{

    protected $parameter = 'filter_location';

    protected $label     = 'Location';

    public function values()
    {

        //... Always return a [value => label ...] associative array
        return [
            'ny' => __('New York'),
            'nb' => __('Nairobi'),
            'fr' => __('France'),
        ];

    }

}
```

Here you can adjust 3 things:

- `$parameter`: The URL parameter to be used for this filter.
- `$label`: Label to be printed.
- `values()`: array of `['value' => 'label', ...]` elements. You can load these values from the database, an API, hardcoded, etc.

Optional:

- `$asArray`: Send this URL parameter as an array instead of a single string with a separator. By defaut is `false`.
- `$separator`: character used to separate values on the URL. By defaut is `,`.

2.2 Create a Sorter (optional)
------------------------------

[](#22-create-a-sorter-optional)

A sorter is actually a filter, so the step to create it is the same as `2.1`.

The only difference is that we should only allow one selected option at a time.

To acomplish this you have to inherit from `SingleSelector` instead of a `MultipleSelector`.

3. Add those filters to the section
-----------------------------------

[](#3-add-those-filters-to-the-section)

The following example Section contains two filters (Department and Location), and a sorter (SortStaff).

```
// Filters
use App\Filters\Definitions\Department;
use App\Filters\Definitions\Location;

// Sorter
use App\Filters\Definitions\SortStaff;

class StaffFiltering extends Petrelli\SearchInterfaceBuilder\BaseSection
{

    protected $route = 'staff';

    protected $filters = [
        Department::class,
        Location::class,
    ];

    protected $sorter = SortStaff::class;

}
```

4. Use the Section object in your view
--------------------------------------

[](#4-use-the-section-object-in-your-view)

From the controller we send the object to the view:

```
return view('staff.index', [
    'filtering' => app(StaffsFiltering::class),
    // ...
]);
```

And from them we can print everything in our views.

Usage: Print filter titles
--------------------------

[](#usage-print-filter-titles)

Used to print the names of each filter to build the top section:

[![A section](/docs/images/filters.png "Section")](/docs/images/filters.png)

```
@foreach ($filtering->filters() as $filter)
  {{ $filter->label() }}
@endforeach
```

Usage: Print all filter options
-------------------------------

[](#usage-print-all-filter-options)

Here we print each one of the options:

[![A section](/docs/images/selected.png "Section")](/docs/images/selected.png)

```
@foreach ($filtering->filters() as $filter)
    {{ $filter->label() }}

    @foreach($filter->links() as $option)

            {{ $option->label }}

    @endforeach

@endforeach
```

Each option object contains the following attributes:

```
$option->label   // Label
$option->value   // Value
$option->active  // Boolean that indicates if is active
$option->urlRoot // URL with no filters at all
$option->url     // URL that contains or not the value depending if it's active (url-present) or not
```

For 99% of use cases you will only have to use `url`, `active`, and `label`.

Usage: Print a list with the selected filters
---------------------------------------------

[](#usage-print-a-list-with-the-selected-filters)

[![A section](/docs/images/selected-list.png "Section")](/docs/images/selected-list.png)

As you will see at the live example after selecting a few filters, that list can be automatically generated.

```
@if ($filters->activeFilters()->isNotEmpty())
    @foreach($filters->activeFilters() as $filter)
      {{ $filter->label }}
    @endforeach

    Clear all

@endif
```

This list will include all selected options within all filters.

Usage: Create a filter that allows only one selected element
------------------------------------------------------------

[](#usage-create-a-filter-that-allows-only-one-selected-element)

To acomplish this you have to inherit from `SingleSelector` instead of `MultipleSelector`.

```
class Location extends Petrelli\SearchInterfaceBuilder\SingleSelector
```

Usage: Build a custom route for a specific filter
-------------------------------------------------

[](#usage-build-a-custom-route-for-a-specific-filter)

Just overload the `buildRoute` function inside your filter class.

```
public function buildRoute($extraParams)
{

    return route($this->route, request()->except(['page', $this->parameter]) + $extraParams);

}
```

TODO
====

[](#todo)

- Improve documentation
- Examples
- Tests

License
=======

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

25

—

LowBetter than 35% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~91 days

Total

4

Last Release

2284d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4fc70d39bb6fe2c649062145018204aba8004821722ec6699cb456c18f4db005?d=identicon)[petrelli](/maintainers/petrelli)

---

Top Contributors

[![ferpetrelli](https://avatars.githubusercontent.com/u/421480?v=4)](https://github.com/ferpetrelli "ferpetrelli (10 commits)")

---

Tags

buildercomposerfilterslaravelsearchinterfacecontrollerfiltersscopesbuildscoped

### Embed Badge

![Health badge](/badges/petrelli-search-interface-builder/health.svg)

```
[![Health](https://phpackages.com/badges/petrelli-search-interface-builder/health.svg)](https://phpackages.com/packages/petrelli-search-interface-builder)
```

###  Alternatives

[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135224.7k7](/packages/statamic-rad-pack-runway)[api-platform/laravel

API Platform support for Laravel

58171.5k14](/packages/api-platform-laravel)[ecotone/laravel

Ecotone for Laravel — CQRS, Event Sourcing, Sagas, Durable Workflows, and Outbox on top of Laravel Queue, via PHP attributes.

21318.6k3](/packages/ecotone-laravel)[duncanmcclean/statamic-cargo

Comprehensive e-commerce addon for Statamic. Build bespoke e-commerce sites without the complexity.

3416.9k](/packages/duncanmcclean-statamic-cargo)[millat/laravel-hooks

The WordPress filter, action system in Laravel

5817.5k](/packages/millat-laravel-hooks)[mobileka/scope-applicator

Scope Applicator is a PHP trait that makes data filtering and sorting easy.

251.2k2](/packages/mobileka-scope-applicator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
