Yii2 gridview + 没有activerecord的过滤

Yii2 gridview + filtering without activerecord

我有一个模型(但是我没有table后面因为我想select关于数据库本身的信息):

namespace app\models;

use Yii;
use yii\base\Model;

class OracleTables extends Model {

    public $table_name;

    public static function getDb() {return Yii::$app->get('db_o');}
}

一个控制器:

namespace app\controllers;

use app\models\OracleTablesSearch;
use yii\web\Controller;
use yii\helpers\Url;
use dmstr\bootstrap\Tabs;

class OracleTablesController extends Controller {

    public function actionIndex() {
        $searchModel = new OracleTablesSearch;
        $dataProvider = $searchModel->search($_GET);

        Tabs::clearLocalStorage();

        Url::remember();
        \Yii::$app->session['__crudReturnUrl'] = null;

        return $this->render('index', [
                    'dataProvider' => $dataProvider,
                    'searchModel' => $searchModel,
        ]);
    }

}

一个搜索模型:

namespace app\models;

use Yii;
use yii\base\Model;
use app\models\OracleTables;
use yii\data\SqlDataProvider;

class OracleTablesSearch extends OracleTables {

    public function rules() {return [[['table_name'], 'safe'],];}

    public function search($params) {
        $totalCount = Yii::$app->db_o
                ->createCommand('SELECT COUNT(TABLE_NAME) FROM USER_TABLES WHERE NUM_ROWS > 0')
                ->queryScalar();

        $dataProvider = new SqlDataProvider([
            'db' => Yii::$app->db_o,
            'sql' => 'SELECT TABLE_NAME FROM USER_TABLES WHERE NUM_ROWS > 0 ORDER BY TABLE_NAME ASC',
            'totalCount' => $totalCount,
        ]);

        $this->load($params);

        return $dataProvider;
    }

}

查看文件:

GridView::widget([
    'dataProvider' => $dataProvider,
    'pager' => ['class' => yii\widgets\LinkPager::className(), 'firstPageLabel' => Yii::t('app', 'First'), 'lastPageLabel' => Yii::t('app', 'Last'),],
    'filterModel' => $searchModel,
    'tableOptions' => ['class' => 'table table-striped table-bordered table-hover'],
    'headerRowOptions' => ['class' => 'x'],
    'columns' => [
        [
            'attribute' => 'TABLE_NAME',
            'contentOptions' => ['nowrap' => 'nowrap'],
            'filter' => AutoComplete::widget([
                'model' => $searchModel,
                'attribute' => 'table_name',
                'clientOptions' => [
                    'source' => [],
                    'autoFill' => true,
                    //'minLength' => 2
                ],
                'options' => ['class' => 'form-control']
            ]),
        ],
    ],
]);

有效,但没有过滤,我也想过滤。我知道如何填充过滤器源,这不是问题所在。问题是,我无法将 $sql->andFilterWhere(['like', 'table_name', $this->table_name]); 添加到搜索模型,因为那样我就需要将 sql 命令转移到 SqlDataProvider 之外,但它不再起作用了。请看这个(搜索型号):

public function search($params) {
    $totalCount = Yii::$app->db_o
            ->createCommand('SELECT COUNT(TABLE_NAME) FROM USER_TABLES WHERE NUM_ROWS > 0')
            ->queryScalar();
    $sql = Yii::$app->db_o
            ->createCommand('SELECT TABLE_NAME FROM USER_TABLES WHERE NUM_ROWS > 0 ORDER BY TABLE_NAME ASC')
            ->queryColumn();

    $dataProvider = new SqlDataProvider([
        'db' => Yii::$app->db_o,
        'sql' => $sql,
        'totalCount' => $totalCount,
    ]);

    $this->load($params);

    $sql->andFilterWhere(['like', 'table_name', $this->table_name]);

    return $dataProvider;
}

如果我这样做,我会收到以下错误消息:

PHP警告

preg_match() 期望参数 2 为字符串,数组给定

在...\vendor\yiisoft\yii2\data\SqlDataProvider.php

131 }

   $sql = $this->sql;
   $orders = [];
   $limit = $offset = null;

   if ($sort !== false) {
       $orders = $sort->getOrders();
       $pattern = '/\s+order\s+by\s+([\w\s,\.]+)$/i';
       if (preg_match($pattern, $sql, $matches)) {
           array_unshift($orders, new Expression($matches[1]));
           $sql = preg_replace($pattern, '', $sql);
       }
   }

   if ($pagination !== false) {
       $pagination->totalCount = $this->getTotalCount();
       $limit = $pagination->getLimit();
       $offset = $pagination->getOffset();

我没找到他说的是什么参数。或者我应该改用什么样的 dataProvider?你能给我指出正确的方向吗?非常感谢!

我是这样解决的:

public $table_name;

public function search($params) {
    isset($_GET['wts']['table_name']) ? $table_name = $_GET['wts']['table_name'] : $table_name = "";

    $totalCount = Yii::$app->db_o
            ->createCommand('SELECT COUNT(TABLE_NAME) FROM USER_TABLES WHERE NUM_ROWS > 0 AND LOWER(TABLE_NAME) LIKE LOWER(:table_name)')
            ->bindValue(':table_name', '%' . $table_name . '%')
            ->queryScalar();

    $dataProvider = new SqlDataProvider([
        'db' => Yii::$app->db_o,
        'sql' => 'SELECT TABLE_NAME, NUM_ROWS FROM USER_TABLES WHERE NUM_ROWS > 0 AND LOWER(TABLE_NAME) LIKE LOWER(:table_name) ORDER BY TABLE_NAME ASC',
        'params' => [':table_name' => '%' . $table_name . '%'],
        'totalCount' => $totalCount,
        'pagination' => [
            'pageSize' => 15,
        ],
    ]);