0

On my system the user can create the column with the name they want, so I save the column name into database

I am using this code on column options:

foreach((new Field)->listFields as $item){

  data = [
    'attribute' => $item->name,
    'value' => function($model){
        return $model->$item->name; // the problem is here, $item->name is out of the scope
     },
  ];
  array_push($columns, $data);
}

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

this is my index view:

<?= \yii\grid\GridView::widget([
   'dataProvider' => $dataProvider,
   'formatter' => ['class' => 'yii\i18n\Formatter'],
   'columns' => $columns,
]); ?>

I want to use the value, because I would like to format the data if the $item->type is X or Y. ex:

'value' => function($model){
    if($item->type == 'img'){
       return Html::img($model->$item->name),
    else {
        return $model->$item->name;
    }
 },

the return of the listField is just an array:

Array
(
    [0] => stdClass Object
        (
            [name] => ITEM_1
            [type] => txt
        )

    [1] => stdClass Object
        (
            [name] => IMAGE_1
            [id] => img
        )

    [2] => stdClass Object
        (
            [name] => IMAGE_2
            [id] => img
        )
)

and the return of the sql in dataProvider is

Array
(
    [0] => Array
        (
            [ITEM_1] => Item 1 blablabla
            [IMAGE_1] => http://url.jpg
            [IMAGE_2] => http://url2.jpg
            [id] => 1
        )

)

As I am using dynamic column, I can't hardcode the column name like $mode->IMAGE_1

ricardo
  • 1,221
  • 2
  • 21
  • 39

2 Answers2

2

As you said, $item is out of scope, and as said in php doc about anonymous functions (not specific to yii) :

Closures may also inherit variables from the parent scope. Any such variables must be passed to the use language construct.

You should simply add use ($item) :

'value' => function($model) use ($item) {
    return $model->{$item->name};
 },

PS: this question should be closed since it is a duplicate

soju
  • 25,111
  • 3
  • 68
  • 70
0

could be you can access to the value using dinamic variable name

    return $model->{$item->name};

or using an array access

  'value' => function($data){
    return $data[{$item->name}] ;
  },
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107