AthenaeumAthenaeum
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
  • Version 6.x

    • Release Notes
    • Upgrade Guide
    • New to this...
    • Contribution Guide
    • Security Policy
    • Code of Conduct
    • Origin
  • ACL

    • Introduction
    • How to install
    • Setup
    • Permissions
    • Roles
    • Users
    • Cached Permissions
  • Audit

    • Audit
    • How to install
    • Setup
    • Recording
    • Events
  • Circuits

    • Circuits
    • How to install
    • Setup
    • Usage
    • Events
  • Collections

    • Collections
    • How to install
    • Summation

      • Summation Collection
      • Items Processor
  • Config

    • Configuration Loader
    • How to install
    • Setup
    • Load Configuration Files
    • Custom File Parsers
  • Console

    • Command and Schedule Registration
    • How to install
    • Setup
    • Commands
    • Schedules
  • Container

    • IoC Service Container
    • How to install
    • Container
    • List Resolver
  • Core

    • Athenaeum Core Application
    • How to install
    • Setup
    • Usage

      • Configuration
      • Service Providers
      • Service Container
      • Events
      • Caching
      • Logging
      • Console
      • Task Scheduling
      • Exception Handling
      • Extending Core Application
      • Testing
  • Database

    • Introduction
    • How to install
    • Models

      • Instantiatable
      • Sluggable
    • Query

      • Criteria (Query Filter)
  • Dto

    • Data Transfer Object (DTO)
    • How to install
    • Create Interface
    • Implement DTO
    • How to use
    • Populate
    • Export
    • Json
    • Serialization
    • Nested DTOs
    • Array DTO
  • ETags

    • ETags
    • How to install
    • Setup
    • Usage
    • Generators

      • Default Generator
      • Custom Generator
    • Eloquent Models
    • Macros
  • Events

    • Register Listeners and Subscribers
    • How to install
    • Setup
    • Listeners
    • Subscribers
  • Filters

    • Search Filter Utilities
    • Prerequisites
    • How to install
    • Setup
    • Processor
    • Filters Builder
    • Predefined Resources

      • Search Processor
      • Sorting Processor
      • Constraints Processor
      • Matching Processor
    • Tip: Create a base builder
  • Flysystem

    • Introduction
    • Database Adapter

      • Introduction
      • How to install
      • Setup
      • Data Deduplication
      • MIME-Type Detection
  • Http

    • Api

      • Http API
      • How to install
      • Setup
      • Resources

        • Introduction
        • Timestamps
        • Self-Link
        • Relations
        • Registrar
      • Middleware

        • Introduction
        • Request Must Be Json
        • Capture Fields To Select
    • Clients

      • Http Clients
      • How to install
      • Setup
      • Basic Usage
      • Available Methods

        • Fluent Api
        • Protocol Version
        • Base Uri
        • Http Method and Uri
        • Headers
        • Accept & Content-Type
        • Authentication
        • Http Query
        • Payload Format
        • Payload
        • Attachments
        • Cookies
        • Response Expectations
        • Middleware
        • Conditions
        • Criteria
        • Redirects
        • Timeout
        • Debugging
        • Logging
        • Driver Options
        • Driver
      • Http Query Builder

        • Introduction
        • Select
        • Where
        • Dates
        • Include
        • Pagination
        • Sorting
        • Raw Expressions
        • Custom Grammar
    • Cookies

      • Http Cookies
      • How to install
      • Usage
    • Messages

      • Http Messages
      • How to install
      • Serializers
  • Maintenance

    • Modes

      • Maintenance Modes
      • How to install
      • Setup
      • Basic Usage
      • Available Drivers
  • Mime Types

    • MIME-Types
    • How to install
    • Setup
    • Usage
    • Drivers

      • Available Drivers
      • File Info
  • Properties

    • Properties Overload
    • How to install
    • Usage
    • Naming Convention
    • Properties Visibility
  • Redmine

    • Redmine Api Client
    • How to install
    • Setup
    • General Usage

      • Supported Operations
      • Fetch list of resources
      • Find
      • Fetch
      • Create new record
      • Update existing record
      • Delete existing record
      • Relations
    • Available Resources

      • Predefined Resources
      • Attachments
      • Enumerations
      • Issue Relations
      • Users
      • User Groups
      • Roles
      • Project Memberships
      • Versions (Milestones)
      • Issue Categories
      • Trackers
  • Service

    • Service Registrar
    • How to install
    • How to use
  • Streams

    • Streams
    • How to install
    • Setup
    • How to use

      • Introduction
      • Open and Close
      • Raw Resource
      • Seeking
      • Reading
      • Writing
      • Size
      • Truncate
      • Flush
      • Hash
      • MIME-Type
      • Output
      • Locking
      • Transactions
      • Meta
      • Misc
  • Support

    • Introduction
    • How to install
    • Laravel Aware-of Helpers

      • How to use
      • Enforce Via Interface
      • Custom Default
      • Pros and Cons
      • Available Helpers
    • Aware-of Properties

      • Generator
      • Available Aware-of Helpers
    • Live Templates
  • Testing

    • Introduction
    • How to install
    • Test Cases
    • Testing Aware-of Helpers
  • Utils

    • Introduction
    • How to install
    • Array
    • Duration
    • Json
    • Math
    • Memory
    • Method Helper
    • Invoker
    • Populatable
    • String
    • Version
  • Validation

    • Introduction
    • How to install
    • Setup
    • Rules

      • Alpha-Dash-Dot
      • Semantic Version
You are viewing documentation for an outdated version. It is no longer supported!

Constraints Processor

As the name implies, the ConstraintsProcessor is able to create constraint query filters, e.g. "where column operator value". The http query string format is slightly inspired by JSON API. The accepted format is:

  • ?identifier[property][operator]=value

Example

  • ?filter[name][contains]=Smith&filter[is_admin][eq]=true

The shown query string will create a query that matches records where name contains Smith and is_admin state is set to true.

  • Setup
    • Properties to column names
    • Maximum amount of allowed filters
    • Logical AND / OR
  • Available Filters
    • Operators
    • Create your own filters
    • BelongsToFilter Example

Setup

When configuring the processor, you must specify the properties and their corresponding "field filter" that can be applied, when requested.

use Aedart\Filters\Processors\ConstraintsProcessor;
use Aedart\Filters\Query\Filters\Fields\NumericFilter;
use Aedart\Filters\Query\Filters\Fields\StringFilter;
use Aedart\Filters\Query\Filters\Fields\BooleanFilter;
use Aedart\Filters\Query\Filters\Fields\DatetimeFilter;

class UserFilterBuilder extends BaseBuilder
{
    public function processors(): array
    {
        return [
            'filter' => ConstraintsProcessor::make()
                ->filters([
                    'id' => NumericFilter::class,
                    'name' => StringFilter::class,
                    'email' => StringFilter::class,
                    'administrator' => BooleanFilter::class,
                    'email_verified' => DatetimeFilter::class,
                    'created_at' => DatetimeFilter::class,
                    'updated_at' => DatetimeFilter::class,
                ])
            
            // ...etc
        ];
    }
}

Properties to column names

Similar to how you can map properties to table column names on the SortingProcessor, the "constraints" processor also offers a propertiesToColumns() method, which can be used to map requested properties to table columns.

return [
    'filter' => ConstraintsProcessor::make()
        ->filters([
            'name' => StringFilter::class,
            'email' => StringFilter::class,
            'administrator' => BooleanFilter::class,
            'email_verified' => DatetimeFilter::class,
        ])
        ->propertiesToColumns([
            'administrator' => 'is_admin',
            'email_verified' => 'email_verified_at'
        ]);
];

Maximum amount of allowed filters

By default, 10 properties are allowed requested to be filtered. When more are requested, then a validation exception will be thrown that results in a 422 Unprocessable Entity response. To change this limit, use the maxFilters() method.

return [
    'filter' => ConstraintsProcessor::make()
        ->maxFilters(15)
        // ...remaining processor config. not shown ...
];

Logical AND / OR

When multiple properties are requested, then constraint filters are applied using logical AND operator. If you wish to allow OR operator, then please see the MatchingProcessor documentation for details.

Available Filters

Within the Aedart\Filters\Query\Filters\Fields\ namespace, you will find a few predefined "field filter". These can be applied per allowed filterable property.

  • NumericFilter matches value against numeric column
  • StringFilter matches value against string column
  • BooleanFilter marches value against boolean column
  • DateFilter matches value against date column (Y-m-d)
  • DatetimeFilter matches value against datetime column (Y-m-d H:i:s)
  • UTCDatetimeFilter matches value against datetime column (Y-m-d H:i:s). Given date is converted to UTC, before matched against database value
  • BelongsToFilter able to constrain relations of the type "belongs to" (see further below for example)

Operators

All available filters support a variety of operators, which can be requested in the http query string. These operators are either mapped directly to an SQL comparison operator or function, which is then applied in the query.

Example

  • eq = =
  • ne = !=
  • gt = >
  • lt = <
  • is_null = is null,
  • contains = like %value%

If an unsupported operator is requested, then the request is aborted - a 422 Unprocessable Entity response is returned. Please review each filter's source for a full list of supported operators.

Create your own filters

If the available filters are not sufficient, then you can create your own filters, which can be supported by the "constraints" processor. The easiest way of doing so, is by extending the BaseFieldFilter abstraction.

Example:

use Aedart\Filters\Query\Filters\Fields\BaseFieldFilter;

class MyFilter extends BaseFieldFilter
{
    public function apply($query)
    {
        $operator = $this->operator();

        switch ($operator) {
            case 'special':
                return $query->where($this->field(), '%', $this->value());

            default:
                return $this->buildDefaultConstraint($query);
        }
    }

    public function operatorAliases(): array
    {
        return [
            'eq' => '=',
            'ne' => '!=',

            'special' => 'special' 
        ];
    }
    
    protected function assertValue($value)
    {
        // The assert method can be used to validate the requested value.
        // Throw an InvalidArgumentException, if value is invalid.
        // The processor will take care of the rest...
    
        if ((int) $value < 1) {
            throw new InvalidArgumentException('Value must be above 1');
        }
    }
}

BelongsToFilter Example

The BelongsToFilter is slightly more special in that you need to create an instance and specify the name of the relation you wish to constrain.

use Aedart\Filters\Query\Filters\Fields\BelongsToFilter;

return [
    'filter' => ConstraintsProcessor::make()
        ->filters([
            'user' => BelongsToFilter::make()
                ->setRelation('owner'),
                
            // ...remaining not shown...
        ])
        ->propertiesToColumns([
            'user' => 'owner.id', // relation + name of column in related model
        ]);
];

String relation

By default, the belongs to filter assumes that the relation value to constrain is an integer. If you wish to constrain a string value instead, e.g. a string column, then use the usingStringValue() method.

return [
    'filter' => ConstraintsProcessor::make()
        ->filters([
            'category' => BelongsToFilter::make()
                ->setRelation('categories')
                ->usingStringValue(),
                
            // ...remaining not shown...
        ])
        ->propertiesToColumns([
            'category' => 'categories.slug',
        ]);
];
Edit page
Last Updated: 16/02/2023, 09:10
Contributors: alin, Alin Eugen Deac
Prev
Sorting Processor
Next
Matching Processor