yii2tech/ar-search

此包已被弃用,不再维护。没有建议的替代包。

为 Yii ActiveRecord 提供统一的搜索模型

资助包维护!
klimov-paul
Patreon

安装数: 7,868

依赖: 0

建议者: 0

安全: 0

星标: 30

关注者: 6

分支: 3

开放问题: 0

类型:yii2-extension

1.0.1 2020-03-04 11:19 UTC

This package is auto-updated.

Last update: 2022-01-10 10:46:03 UTC


README

12951949

为 Yii2 的 ActiveRecord 搜索模型扩展


此扩展为 Yii ActiveRecord 提供统一的搜索模型。

有关许可证信息,请参阅 LICENSE 文件。

Latest Stable Version Total Downloads Build Status

安装

安装此扩展的首选方式是通过 composer

运行以下命令:

php composer.phar require --prefer-dist yii2tech/ar-search

或者将以下内容添加到您的 composer.json 文件中的 require 部分:

"yii2tech/ar-search": "*"

(此处省略具体命令和代码)

使用方法

此扩展通过特殊模型类 \yii2tech\ar\search\ActiveSearchModel 为 Yii ActiveRecord 提供统一的搜索模型。

此模型能够从通过 \yii2tech\ar\search\ActiveSearchModel::$model 指定的 '奴隶' 源 ActiveRecord 模型中获取其属性、验证规则和过滤逻辑。因此,您无需为搜索声明单独的模型类并定义过滤逻辑。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;

$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item'
]);
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

ActiveSearchModel 会选择 '奴隶' 模型的所有 '安全' 属性,并将它们用作自己的属性。因此,您可以在此类的作用域内使用任何标记为 '安全' 的相关 ActiveRecord 模型的属性。例如

<?php

namespace app\models;

// ActiveRecord to be searched:
class Item extends \yii\db\ActiveRecord
{
    public function rules()
    {
        return [
            [['name', 'status', 'price'], 'required'],
            ['name', 'string'],
            ['status', 'integer'],
            ['price', 'number'],
        ];
    }
}

use yii2tech\ar\search\ActiveSearchModel;

// Create search model for declared ActiveRecord:
$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item'
]);

// safe attributes of `Item` are inherited:
$searchModel->name = 'Paul';
$searchModel->price = 10.5;

在组合应收集过滤数据的 Web 表单时,可以使用继承的属性。例如

<?php
use yii2tech\ar\search\ActiveSearchModel;
use yii\widgets\ActiveForm;

$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item'
]);
?>
<?php $form = ActiveForm::begin(); ?>

<?= $form->field($model, 'name')->textInput() ?>
<?= $form->field($model, 'price')->textInput() ?>
...

<?php ActiveForm::end(); ?>

属性标签和提示也继承自 '奴隶' 模型。

\yii2tech\ar\search\ActiveSearchModel 的主要方法是 search()。它从给定的数据数组中加载过滤属性,验证它们并创建一个 \yii\data\ActiveDataProvider 实例,应用自己的属性作为查询过滤条件。

ActiveSearchModel 使用基于 \yii2tech\ar\search\ActiveSearchModel::$searchAttributeTypes 中指定的属性类型的高级逻辑进行查询过滤,其值默认从 \yii2tech\ar\search\ActiveSearchModel::$model 中提取,并使用通过 \yii2tech\ar\search\ActiveSearchModel::$filterOperators 指定的过滤操作符列表。默认情况下,将使用 \yii\db\QueryInterface::andFilterWhere() 进行过滤组合。对于 '字符串' 属性,将使用 'like' 操作符。对于 '整数' 和 '浮点' ('双精度浮点') 属性,如果可用,将使用 andFilterCompare() 方法。

注意!不要过度使用 ActiveSearchModel。它被设计用来仅覆盖最简单的场景,其中搜索逻辑简单。如果需要复杂的搜索查询组合逻辑,您应始终创建一个单独的搜索模型。

调整数据提供者

您可能想要更改由 search() 方法创建的数据提供者的某些设置:更改分页或排序设置等。您可以通过 \yii2tech\ar\search\ActiveSearchModel::$dataProvider 来这样做。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;

$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item',
    'dataProvider' => [
        'class' => 'yii\data\ActiveDataProvider',
        'pagination' => [
            'defaultPageSize' => 40
        ],
    ],
]);
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
echo $dataProvider->pagination->defaultPageSize; // outputs `40`

调整搜索查询

您可以使用 \yii2tech\ar\search\ActiveSearchModel::EVENT_AFTER_CREATE_QUERY 事件来调整搜索查询实例,添加关系预加载或永久条件。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;
use yii2tech\ar\search\ActiveSearchEvent;

$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item',
]);
$searchModel->on(ActiveSearchModel::EVENT_AFTER_CREATE_QUERY, function(ActiveSearchEvent $event) {
    $event->query
        ->with(['category'])
        ->andWhere(['status' => 1]);
});

您还可以直接通过 \yii2tech\ar\search\ActiveSearchModel::$dataProvider 指定查询对象。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;
use yii\data\ActiveDataProvider;
use app\models\Item;

$searchModel = new ActiveSearchModel([
    'model' => Item::className(),
    'dataProvider' => function () {
        $query = Item::find()
            ->with(['category'])
            ->andWhere(['status' => 1]);

        return ActiveDataProvider(['query' => $query]);
    },
]);

过滤器运算符

您可以通过 \yii2tech\ar\search\ActiveSearchModel::$filterOperators 控制用于查询过滤的运算符。它定义了属性类型与用于 \yii\db\QueryInterface::andFilterWhere() 的运算符之间的映射。每个值可以是标量运算符名称或 PHP 回调,接受查询实例、属性名称和值。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;

$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item',
    'filterOperators' => [
        ActiveSearchModel::TYPE_STRING => '=', // use strict comparison for the string attributes
        ActiveSearchModel::TYPE_INTEGER => function (\yii\db\ActiveQueryInterface $query, $attribute, $value) {
            if ($attribute === 'commentsCount') {
                $query->andHaving(['commentsCount' => $value]);
            } else {
                $query->andFilterWhere([$attribute => $value]);
            }
        },
    ],
]);

ActiveSearchModel 允许使用查询的 andFilterCompare() 方法(例如:\yii\db\Query::andFilterCompare())对属性进行过滤,允许指定格式为 {operator}{value} 的过滤器值(例如:>10<=100 等)。允许使用此类比较的属性名称列表由 \yii2tech\ar\search\ActiveSearchModel::$compareAllowedAttributes 控制。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;

$searchModel = new ActiveSearchModel([
    'model' => 'app\models\Item',
    'compareAllowedAttributes' => [
        'price' // allow compare for 'price' only, excluding such fields like 'categoryId', 'status' and so on.
    ],
]);

您可以将 compareAllowedAttributes 设置为 *,这表示任何浮点数或整数属性都将允许进行比较。

注意:\yii2tech\ar\search\ActiveSearchModel::$filterOperators 优先于 \yii2tech\ar\search\ActiveSearchModel::$compareAllowedAttributes

在不使用 '从' 模型的情况下工作

尽管在大多数情况下,设置 \yii2tech\ar\search\ActiveSearchModel::$model 是配置 ActiveSearchModel 实例的最快方式,但它不是必需的。您可以避免设置 '从' 模型,并直接配置所有与搜索相关的属性。例如

<?php

use yii2tech\ar\search\ActiveSearchModel;
use yii\data\ActiveDataProvider;
use app\models\Item;

$searchModel = new ActiveSearchModel([
    'searchAttributeTypes' => [
        'id' => ActiveSearchModel::TYPE_INTEGER,
        'name' => ActiveSearchModel::TYPE_STRING,
        'price' => ActiveSearchModel::TYPE_FLOAT,
    ],
    'rules' => [
        ['id', 'integer'],
        ['name', 'string'],
        ['price', 'number'],
    ],
    'compareAllowedAttributes' => [],
    'dataProvider' => function () {
        $query = Item::find()
            ->with(['category'])
            ->andWhere(['status' => 1]);

        return ActiveDataProvider(['query' => $query]);
    },
]);