yii2tech / ar-search
为 Yii ActiveRecord 提供统一的搜索模型
Requires
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- phpunit/phpunit: 4.8.27 || ^5.0 || ^6.0
This package is auto-updated.
Last update: 2022-01-10 10:46:03 UTC
README
为 Yii2 的 ActiveRecord 搜索模型扩展
此扩展为 Yii ActiveRecord 提供统一的搜索模型。
有关许可证信息,请参阅 LICENSE 文件。
安装
安装此扩展的首选方式是通过 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]); }, ]);