0
votes

I have this problem: I need to get data from database and filter them. but then I need to use custom php function to filter those filtered results using data from it.

Clasic search function in ActiveDataProvider

public function search($params) {

    $query = Passenger::find();

    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    // I guess my function would go like here
    Passenger::filterResultsEvenMore($dataProvider);

    $this->load($params);

    if (!$this->validate()) {
        // uncomment the following line if you do not want to return any records when validation fails
        // $query->where('0=1');
        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere([
        'passenger_id' => $this->passenger_id,
        // ...
        'version' => $this->version,
        'status' => $this->status,
    ]);

    return $dataProvider;
}

So my question is how to work with results of dataProvider because if I vardump the variable it looks like this and no actual data there.

yii\data\ActiveDataProvider Object
(
    [query] => common\models\PassengerQuery Object
        (
            [sql] => 
            [on] => 
            [joinWith] => 
            [select] => 
            [selectOption] => 
            [distinct] => 
            [from] => 
            [groupBy] => 
            [join] => 
            [having] => 
            [union] => 
            [params] => Array()
            [_events:yii\base\Component:private] => Array()
            [_behaviors:yii\base\Component:private] => Array()
            [where] => Array
                (
                    [status] => 1
                )
            [limit] => 
            [offset] => 
            [orderBy] => 
            [indexBy] => 
            [emulateExecution] => 
            [modelClass] => common\models\Passenger
            [with] => 
            [asArray] => 
            [multiple] => 
            [primaryModel] => 
            [link] => 
            [via] => 
            [inverseOf] => 
        )
    [key] => 
    [db] => 
    [id] => 
    [_sort:yii\data\BaseDataProvider:private] => 
    [_pagination:yii\data\BaseDataProvider:private] => 
    [_keys:yii\data\BaseDataProvider:private] => 
    [_models:yii\data\BaseDataProvider:private] => 
    [_totalCount:yii\data\BaseDataProvider:private] => 
    [_events:yii\base\Component:private] => Array()
    [_behaviors:yii\base\Component:private] => 
)

UPDATE

I need to use function like this for each record:

if (myFunction(table_column_1, table_column_2)) {
    result_is_ok_return_it
} else {
    do_not_return_this_record
}
3
use $dataProvider->models to get result. - Insane Skull
is it that easy? I cant believe that, I had weak moment I guess, thanks man, if you write it as reply I will rate it up - Ripper

3 Answers

1
votes

Why do you don't add your additional filters to query object used in DataProvider? You can parse your conditions to $query->andFilterWhere(). If you need custom function for it just modify $dataProvider->query object inside function. After execute query in data provider you can only filter results by manually filter array of models stored in $dataProvider->models

1
votes

To get result use models property or getModels()

For example,

$dataProvider->models;

OR

$dataProvider->getModels();
0
votes

I think I came across a solution, (looks like it is working)

http://www.yiiframework.com/doc-2.0/yii-data-basedataprovider.html#setModels()-detail

After I do all my usual search stuff as described in question at beginning, I would do something like this using setModels() function

class PassengerSearch extends Passenger

    public $status; // virtual attribute not present in database table

    public function rules()
    {
        return [
            // ... some other rules
            [['status'], 'safe'],
        ];
    }

    // ...

    $filtered_models = [];
    $filter_models = false; // if you only want to filter if there is some value

    foreach ($dataProvider->models as $model) {
        // if ($model->status == 1) // example
        if (!empty($this->status) && $model->status == $this->status) { // better approach, using virtual attribute $status
            $filter_models = true;
            $filtered_models[] = $model;
        }
    }

    if ($filter_models)
        $dataProvider->setModels($filtered_models);

    return $dataProvider;
}