3

Using Yii2 I'll need to provide a DataProvider with specific data. The problem is that I need to create a single DataProvider with an array data and data from a table in a database.

Therefore, I think that I should mix an ArrayDataProvider and an ActiveDataProvider. I don't know if Yii2 offers tools for this situations or should I create my own DataProvider from BaseDataProvider.

I cant post some code because is a knowledge question.

Sageth
  • 1,102
  • 1
  • 15
  • 30
  • 1
    Hi, please post some code and add more info on how you want to "mix" the 2 dataproviders. You want to add some more "columns" to the data from the DB? Or you want to add all the rows of the database with the array? A sample of the data would be nice to see – Asped Oct 02 '15 at 11:50
  • @Asped I need the data from a table, and need to merge with data with the same structure, but i dont want to store it in the DB. The problem is I need to manage all data like one dataprovider. Is a bit weird question. – Sageth Oct 02 '15 at 13:46

2 Answers2

2

According to your description, you could try to get the data from the DB as an Array, then merge it with the other array you have, and then put it all in an ArrayDataProvider

Try this (not tested):

$dbData = Model::find()->all(); //load your data from DB
$arrayData = [...]; //your other data as an array

// do the merge, with ArrayHelper::merge() or somehow manually

$data = ArrayHelper::merge($dbData, $arrayData);
$provider = new ArrayDataProvider([
'allModels' => $data
]);
Asped
  • 3,083
  • 4
  • 31
  • 52
0

Yes, Asped's approach will work. Here's a working example, in a Model function - in this case I'm merging a SqlDataProvider and an ActiveDataProvider, to merge data from two tables, but the same principle would apply to merging any other combination of DataProviders (yes, I did test the other combinations):

/**
 * @return ArrayDataProvider;
 * 
 * Combine current Activity with Archive:
 */
public function getActivityCombined() {

    # Current:
    $dataProviderActivityCurrent = new SqlDataProvider([
        'sql' => 'SELECT listing_id, counter_reset, impress_town, impress_county, 
                                    impress_listing, clicks_web, clicks_facebook, clicks_twitter 
                                    FROM listing WHERE listing_id = ' . $this->listing_id,
    ]);

    # Archive:
    $query = ActivityArchive::find();
    $dataProviderActivityArchive = new ActiveDataProvider([
            'query' => $query,
    ]);
    $dataProviderActivityArchive->query->andWhere(['listing_id' => $this->listing_id]);

    # Merge:
    $dataMerge = array_merge($dataProviderActivityCurrent->getModels(), $dataProviderActivityArchive->getModels());
    $dataProviderActivity = new ArrayDataProvider([
        'allModels' => $dataMerge
    ]);

    # Return combined:
    return $dataProviderActivity;

}

Of course you'll need to include use statements for the three DataProvider types.

The model function is then called by a GridView widget in a view:

echo GridView::widget([
    'dataProvider' => $model->getActivityCombined(),
    'columns' => [
            'counter_reset',
            'impress_town',
            'impress_county',
            'impress_listing',
            'clicks_web',
            'clicks_facebook',
            'clicks_twitter',
    ],
]);
Rich Harding
  • 645
  • 6
  • 14