Custom Data Provider using foreach

Hi! Im trying to create a custom dataProvider made out of Profesores id’s (teachers id’s).
My site hosts information about teachers, courses, grades, etc. for schools.

The User Alumno (student) will see a gridview of it’s Profesores for each course he’s registered in, so, I’m trying to return that information in a dataProvider.

First, I ask if the User is an Alumno.

Then I search for the Asignaturas the Alumno is registered in.

With that information, I search for the Profesors that teaches that Cursos, to return it’s id’s as a dataProvider, so I made a foreach cycle.

What I need is an array of Profesores id’s so I can show Profesors’s names in the grid view. The actual code is quering the last Profesor id into the dataProvider.

public function actionIndex()
    {        
        $this->layout = 'main';
        $searchModel = new ProfesorSearch();
        
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        if(User::isUserAlumno(Yii::$app->user->identity->id)){
            $alumno = Alumno::find()->where(['id_usuario' => Yii::$app->user->identity->id])->one();
            $asignaturas = Asignatura::find()->where(['id_curso' => $alumno->id_curso])->all();
            foreach ($asignaturas as $asignatura){
                $dataProvider = new ActiveDataProvider([
                'query' => Profesor::find()->where(['id' => $asignatura->id_profesor])
                ]);
            }
        }
        
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

Any help would be appreciated. @softark @samdark

Can you do it with just SQL?

I don’t know how to do it with a query builder because gridview needs a data provider

I tried this with no success

public function actionIndex()
    {        
        $this->layout = 'main';
        $searchModel = new ProfesorSearch();
        
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        if(User::isUserAlumno(Yii::$app->user->identity->id)){
            $alumno = Alumno::find()->where(['id_usuario' => Yii::$app->user->identity->id])->one();
            $asignaturas = Asignatura::find()->where(['id_curso' => $alumno->id_curso])->all();
            foreach ($asignaturas as $asignatura){
                $query = (new yii\db\Query())
                    ->from('Profesor')
                    ->where("id=$asignatura->id_profesor");
            }
            
            //  Crear un comando. Se puede obtener la consulta SQL actual utilizando $command->sql
            $command = $query->createCommand();

            // Ejecutar el comando:
            $rows = $command->queryAll();
            
            return $this->render('index', [
                'rows' => $rows
        ]);
            
        }
        
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

I also tried this

public function actionIndex()
    {        
        $this->layout = 'main';
        $searchModel = new ProfesorSearch();
        
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        if(User::isUserAlumno(Yii::$app->user->identity->id)){
            $alumno = Alumno::find()->where(['id_usuario' => Yii::$app->user->identity->id])->one();
            $asignaturas = Asignatura::find()->where(['id_curso' => $alumno->id_curso])->all();
            foreach ($asignaturas as $asignatura){
                $dataProvider = new SqlDataProvider([
                    'sql' => 'SELECT * FROM profesor WHERE id=' . $asignatura->id_profesor,
                    ]);
            }
        }
        
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);

And shows me the following error:

Trying to get property 'id' of non-object
1. in C:\xampp\htdocs\sie\views\profesor\index.phpat line 140
131132133134135136137138139140141142143144145146147148149                
'update' => function ($url, $model) {
                    return Html::button('',[
                        'class' => 'glyphicon glyphicon-pencil btn_update_pencil',
                        'id' => 'btn_update_profesor',
                        'data-dismiss' => 'modal',
                        'onclick' => '$(function(){
                                            $("#update_profesor").modal("show")
                                                .find("#modal-update-profesor")
                                                .load("index.php?r=profesor/update' .
                                                    '&id=' . $model->id .'");
                                        });'
                    ]);
                    },
                ],
                            ],
            ],
        ]); ?>
    </p>

Hi @jc.reyes.suazo,

First of all, could you explain a bit more about your ER?
What I understand is that …

  1. Alumno has one Curso via alumno.id_curso,
  2. Curso has one Profesor via curso.id_profesor,
  3. Asignatura has one Curso via asignatura.id_curso, and
  4. Asignatura has one Profesor via asignatura.id_profesor.

Am I right in this understanding?

And, have you already established the relations among them? If you have used Gii to generate the model classes, Gii should have done it for you.

With the proper definitions of the relations, there’s no need to do the things that you are trying to do now.

For example, if you can get an Alumno, you can get the profesors.

$alumno = Alumno::findOne(['id_usuario' => Yii::$app->user->identity->id]);
$curso = $alumno->curso;
$asignaturas = $curso->asignaturas;
foreach ($asignaturas as $asignatura) {
    $profesor = $asignatura->profesor;
    ...
}

Or if you want to retrieve the array of profesors;

$alumno = Alumno::findOne(['id_usuario' => Yii::$app->user->identity->id]);
$profesors = Profesor::find()
    ->joinWith('asignatura')
    ->where(['asignatura.id_curso' => $alumno->id_curso])
    ->distinct()
    ->all();

I’ve meant plain SQL without any PHP code.

@jc.reyes.suazo Posted answer on Stackoverflow

1 Like

I tried but im not that good in sql. Thanks anyway.

You got it right. I should have posted my relations between models. Sorry for that.

Yes I did it with gii but there was one relation left behind because I created it after I generated the models with gii.

I thank you enormously for your help and effort. You always come to help me when I need it.
I tried your solution but, as I said, I need a dataProvider for the gridview, so I’m staying with @InsaneSkull solution.

Thank you mate, your solution works for me. I’ll accept your answer inmediatly in stackoverflow.