2017-02-22 40 views
1

У меня есть модель (но я dont't есть таблица позади, потому что я хочу, чтобы выбрать информацию о самой базе данных):Yii2 GridView + фильтрация без ActiveRecord

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 быть строка, массив дал

в ... \ поставщика \ 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 я должен использовать вместо этого? Не могли бы вы указать мне правильное направление? Большое спасибо!

ответ

1

Я решил это так:

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, 
     ], 
    ]);