承接 asemalalami/laravel-advanced-filter 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

asemalalami/laravel-advanced-filter

Composer 安装命令:

composer create-project asemalalami/laravel-advanced-filter

包简介

Laravel Advanced Filter

README 文档

README

This package allows you to filter on laravel models

You can choose fields to filtering and customize its data-types, aliases and excepted operators, you can add/customize your request format, and you add new operators or overwrite the existed operators

Installation

You can install the package via composer:

composer require asemalalami/laravel-advanced-filter

The package will automatically register its service provider.

You can optionally publish the config file with:

php artisan vendor:publish --provider="AsemAlalami\LaravelAdvancedFilter\AdvancedFilterServiceProvider" --tag="config"

These default config file that will be published: Config File

Usage

  • use HasFilter trait in the model
  • add fields in the implementation of the abstract function setupFilter
  • call the filter scope in your controller
class Order extends Model
{
    use HasFilter;

    protected $casts = [
        'void' => 'boolean',
    ];

    public function channel()
    {
        return $this->belongsTo(Channel::class);
    }

    public function orderLines()
    {
        return $this->hasMany(OrderLine::class);
    }

    public function setupFilter()
    {
        $this->addField('void'); // will cast to 'boolean' from the model casts
        $this->addField('total')->setDatatype('numeric');
        $this->addFields(['source', 'subsource', 'order_date']);
        // field from relation
        $this->addFields(['channel.created_at' => 'channel_create'])->setDatatype('date');
        $this->addField('orderLines.product.sku', 'product_sku');
        // field from relation count
        $this->addCountField('orderLines');
        // custom field (raw sql)
        $this->addCustomField('my_total', '(shipping_cost + subtotal)');
        // enable general search
        $this->addGeneralSearch(['source', 'orderLines.product.sku'], 'startsWith');
    }

    // customize field filter by custom scope
    public function scopeWhereSource(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')
    {
        if ($operator == 'Equal') {
            return $builder->where(function (Builder $builder) use ($value) {
                $builder->where('source', $value)
                    ->orWhere('subsource', $value);
            });
        }
        
        // default behavior
        return $builder->applyOperator($operator, $field, $value, $conjunction);
    }
}

...

class OrderController extends Controller
{
    public function index()
    {
        return Order::filter()->paginate(); // you can pass your custom request
    }
}

Query Format

Query format is the shape that you want to send your query(filters) in the request. the package support 3 formats, and you can create a new format.

  • json (default): the filters will send as json in the request

    filters=[{"field":"email","operator":"equal","value":"abc"}]
  • array: the filters will send as array in the request

    filters[email][value]=abc&filters[email][operator]=equal
    
  • separator: the filters will send as well as in the array format, but separated by a separator(^ default)

    the format sets with a separator symbol separator:^

    filters^email^value=abc&filters^email^operator=equal
    

set the default query format in the config file query_format attribute

Create a new query format:

  • create a new class and extends it from QueryFormat: class MyFormat extends QueryFormat
  • implement the abstract function format that returns FilterRequest object
  • add the class to the config file in custom_query_format attribute: 'custom_query_format' => MyFormat::class,

Fields

Normal Field options:

  • field name is the column name

  • alias is the key that you want to send in the request

  • data-type: by default it set from model casts, if you want to set custom data-type, use setDatatype

  • operators: the field will accept all operators unless you use setExceptedOperators to exclude some operators

  • a relational field: only set the field name by . separator channel.name, channel.type.name

    you can define field name by . separator, but you want to consider it as a non relational field by pass false for inRelation parameter (used in NoSQL DB or join between tables)

    $this->addField('channels.name', 'channel_name', false);
  • customize a field query, you can make a scope for the field to customize the filter behavior. scope name must be combined 3 sections :

    • scope
    • the value of prefix_scope_function key in config file (where is the default)
    • field name(or relation name) for example email
    public function scopeWhereEmail(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')

    you can customize a relational field by define the scope in the relation model OR define scope by relation name

    OrderLine.php
    
    public function scopeWherePrice(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')
    
    OR
    
    Order.php
    
    public function scopeWhereOrderLines(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')

    you can use applyOperator function to use the default behavior $builder->applyOperator($operator, $field, $value, $conjunction);

You can add fields to a model by using 4 functions:

  • addField(string $field, string $alias = null, ?bool $inRelation = null): by default alias value same as field name value
    $this->addField('total')->setDatatype('numeric');
  • addFields($fields): accept an array of field and aliases:
    $this->addFields(['created_at' => 'create_date', 'order_date'])->setDatatype('date');
  • addCountField(string $relation, string $alias = null, callable $callback = null): add a field from count of relation, use can customize the count query and alias(by default is concat relation name(snake case) and _count)
    $this->addCountField('orderLines');
    
    $this->addCountField('orderLines', 'lines_count', function (Builder $builder) {
        $builder->where('quantity', '>', 1);
    });
  • addCustomField(string $alias, string $sqlRaw, $relation = null): add a field from raw sql query
    $this->addCustomField('my_total', '(`shipping_cost` + `subtotal`)');
    $this->addCustomField('line_subtotal', '(`price` + `quantity`)', 'orderLines'); // inside "orderLines" relation

General Search

You can enable general search on some fields, and you can specify the operator (startsWith is the default operator)

$this->addGeneralSearch(['source', 'orderLines.product.sku'], 'startsWith');

Conjunction

Currently, the package support one conjunction between all fields and | or, default conjunction attribute in the config file default_conjunction

Operators

The package has many operators, you can create new operators, and you can customize the operators aliases that you want to send in the request

  • Equals (=, equals)
  • NotEquals (!=, notEquals)
  • GreaterThan (> , greater)
  • GreaterThanOrEqual (>=, greaterOrEqual)
  • LessThan (<, less)
  • LessThanOrEqual (<=, lessOrEqual)
  • In (|, in)
  • NotIn (!|, notIn)
  • Contains (*, contains)
  • NotContains (!*, notContains)
  • StartsWith (^, startsWith)
  • NotStartsWith (!^, notStartsWith)
  • EndsWith ($, endsWith)
  • NotEndsWith (!$, notEndsWith)
  • Between (><, between)

Create a new Operator:

  • create a new class and extends it from Operator: class MyOperator extends Operator
  • implement the abstract function apply and getSqlOperator (used as a default sql operator for count and custom field)
  • add the class in the config file in custom_operators attribute: 'custom_operators' => [MyOperator::class => ['my-op', '*']],

Data Types:

  • boolean
  • date
  • datetime
  • numeric
  • string

Config

Config File

asemalalami/laravel-advanced-filter 适用场景与选型建议

asemalalami/laravel-advanced-filter 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 816 次下载、GitHub Stars 达 32, 最近一次更新时间为 2020 年 11 月 15 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「filter」 「laravel」 「filters」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 asemalalami/laravel-advanced-filter 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 asemalalami/laravel-advanced-filter 我们能提供哪些服务?
定制开发 / 二次开发

基于 asemalalami/laravel-advanced-filter 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 816
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 32
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 32
  • Watchers: 2
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2020-11-15