# Query Scopes

## Definition

A Query Scope is a sort of complex condition you can add easily to an Eloquent Query.

{% hint style="info" %}
For more information about Query Scopes, please refer to the [Laravel official documentation](https://laravel.com/docs/5.7/eloquent#query-scopes).
{% endhint %}

By default, Uccello provides 3 query scopes:

* inDomain
* filterBy
* assignedUser

## Default Query Scopes

### inDomain

This [local scope](https://laravel.com/docs/5.7/eloquent#local-scopes) allows to easily filter the records of a module, to visualize only those of the current domain or its child domains if the descending view is activated.

{% hint style="info" %}
This scope is activated only if the module contains a `domain_id` column in this related database table.
{% endhint %}

The following example will retrieve all people related to the domain with the slug `uccello`:

```php
<?php

use App\Person;
use Uccello\Core\Models\Domain;

$domain = ucdomain('uccello');

// Only people belonging to the uccello domain
$people = Person::inDomain($domain)->get();

 // People belonging to the uccello domain and its descendants domains
$people = Person::inDomain($domain, true)->get();
```

You can use this scope with other conditions:

```php
<?php

// People belonging to the uccello domain and its descendants domains
// and with a name starting with 'John'.
$people = \App\Person::inDomain(ucmodule('uccello'), true)
    ->where('name', 'like', 'John%')
    ->get();
```

### filterBy

This [local scope](https://laravel.com/docs/5.7/eloquent#local-scopes) allows to filter records of a module. You can pass a filter's `id`, a filter `object` or an `array` containing the description of the filter you want to apply.

{% hint style="info" %}
If you use an existing filter, only the `conditions` and the sort `order` will be applied. The `columns` definition will be ignored.
{% endhint %}

```php
<?php

use App\Person;
use Uccello\Core\Models\Domain;

// Apply the filter with the id 1 to the query
$people = Person::filterBy(1)->get();

// Retrieve a filter and apply it to the query
$filter = Filter::find(1);
$people = Person::filterBy($filter)->get();

// Apply a custom filter
$customFilter = [
    'conditions' => [ 
        "search"  => [
            "first_name" => "John"
        ]
    ],
    'order' => [ 'last_name' => 'asc' ]
];
$people = Person::filterBy($customFilter)->get();
```

You can use this scope with other conditions:

```php
<?php

// Apply the filter with the id 1 to the query
// to people belonging to the uccello domain and its descendants domains
// and with a name starting with 'John'.
$people = App\Person::inDomain(ucmodule('uccello'), true)
    ->where('name', 'like', 'John%')
    ->filterBy(1)
    ->get();
```

### assignedUser

This [global scope](https://laravel.com/docs/5.7/eloquent#global-scopes) is automatically applied by default to **all queries of all private modules** and allows to retrieve records only if there are assigned to the authenticated user of to a group to which he belongs. It is applied only if a column `assigned_user_id` exists in the database table related of the module. For more information see [AssignedUser Uitype documentation](../../uitypes-displaytypes/default-uitypes#assigned-user).

{% hint style="info" %}
This global scope is initialized in the [UccelloModule](https://github.com/uccellolabs/uccello/blob/master/app/Support/Traits/UccelloModule.php) trait. As explained in the [Laravel official documentation](https://laravel.com/docs/5.7/eloquent#global-scopes), if you would like to remove it for a given query, use the `withoutGlobalScope` method:

`People::withoutGlobalScope(\Uccello\Core\Support\Scopes\AssignedUser::class)`
{% endhint %}
