# Query Scopes & Filters

Query scopes and filters allow you to narrow down query results using custom conditions.

You may create scopes that can be used in various places, such as inside the collection tag or inside control panel listings.

## Scopes

Any scope classes located within `app/Scopes` will be automatically registered.

You may create a scope class by running `php please make:scope YourScope`, which will give you a class with a few methods for you to implement, for example:

``` php
<?php

namespace App\Scopes;

use Statamic\Query\Scopes\Scope;

class Featured extends Scope
{
    public function apply($query, $values)
    {
        $query->where('featured', true);
    }
}
```

The `apply` method will give you a query builder instance, allowing you to modify it how you see fit.

It will also give you `$values`, which will be an array of contextual values. For example, when [using the scope on a collection tag](/tags/collection.md#custom-query-scopes), you will get all the parameter values. When used as a [filter](#filters) inside the control panel, you will get all of your filter's field values.

Example: Suppose a collection named "portfolio" and a dynamically obtained "slug" variable. The scope is called PorfolioScope. In your Antlers template:
``` antlers
{{ collection:portfolio query_scope="portfolio_scope" slug="{portfolio}" }}
    {{ content }}
{{ /collection:portfolio }}
```

In `PortfolioScope`:
``` php
public function apply($query, $values)
{
    $slug = $values['slug'];
    $query->where('slug', $slug);
}
```

This will gives you the content of that page.


### Using scopes programmatically

In order to use a scope as a query builder method, like "local scopes" in Eloquent, you have to register it on the respective query builder:

```php
use Statamic\Facades\Entry;

public function boot()
{
    Entry::allowQueryScope(Featured::class);
}
```
```php
Entry::query()->where('this', 'that')->featured()->get();
```
However, unlike Eloquent's local scopes, Statamic's scopes accept an array of context. Make sure to pass an associative array rather than individual arguments:
```php
$query->featured([
    'field' => 'value',
    'foo' => 'bar',
]);
```



## Filters

Filters are UI based [scopes](#scopes) that will be displayed in listings inside the Control Panel.

You're able to configure any number of fields to a filter to allow your users to refine their listings.

You may create a filter class by running `php please make:filter YourScope`, which will give you a class with a few methods for you to implement, for example:

``` php
<?php

namespace App\Scopes;

use Statamic\Query\Scopes\Filter;

class Featured extends Filter
{
    public function fieldItems()
    {
        return [
            'featured' => [
                'type' => 'radio',
                'options' => [
                    'featured' => __('Featured'),
                    'not_featured' => __('Not Featured'),
                ]
            ]
        ];
    }
    
    public function autoApply()
    {
        return [
            'featured' => 'not_featured',
        ];
    }

    public function apply($query, $values)
    {
        $query->where('featured', $values['featured'] === 'featured');
    }

    public function badge($values)
    {
        return $values['featured'] === 'featured'
            ? __('is featured')
            : __('not featured');
    }

    public function visibleTo($key)
    {
        return $key === 'entries' && $this->context['collection'] == 'blog';
    }
}
```

The `fieldItems` method lets you define which filter fields will be displayed, just like a field inside a Blueprint.

The `apply` method works exactly as it would in a standard [scope](#scopes).

The `badge` method lets you define the badge text to be used when the filter is active on a listing.

The `visibleTo` method allows you to control in which listings this filter will be displayed. You will be given a key that represents the type of listing. For example, an author filter might be appropriate for the `entries` listing but not `users`. You may also be given an array of contextual data which will vary depending on the listing. For instance, for `entries`, the current collection name can be accessed with `$this->context['collection']`.

The `autoApply` method lets you define a default value to apply.

You may also pin your filters to the filters bar by setting the `$pinned` class property:

```php
public $pinned = true;
```
