yii2 ActiveData Provider - yii2

This is my user model
class User extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'user';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[[ 'created_at', 'updated_at', 'branch_id', 'postcode', 'tel_no', 'child_no','company_id'], 'integer'],
// [['branch_id', 'edu_level', 'date_joined','address1','country','state','city','postcode','race','position_level','religion','gender','staff_id','username','password','ic_number','tel_no','marital_status','child_no','bumi_status','resident_status','email','company_id'], 'required'],
[['get_mail', 'gender', 'marital_status', 'resident_status', 'bumi_status','designation','status'], 'string'],
[['date_joined'], 'safe'],
[['staff_id', 'password', 'edu_level', 'position_level', 'address2', 'address3', 'address4', 'country', 'state', 'city', 'race', 'religion'], 'string', 'max' => 100],
[['username', 'fullname', 'password_hash', 'password_reset_token', 'email', 'auth_key'], 'string', 'max' => 255],
[['ic_number'], 'string', 'max' => 14],
[['address1'], 'string', 'max' => 1000],
[['staff_id'], 'unique'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('user', 'ID'),
'staff_id' => Yii::t('user', 'Staff ID'),
'username' => Yii::t('user', 'Username'),
'fullname' => Yii::t('user', 'Fullname'),
'password' => Yii::t('user', 'Password'),
'password_hash' => Yii::t('user', 'Password Hash'),
'password_reset_token' => Yii::t('user', 'Password Reset Token'),
'email' => Yii::t('user', 'Email'),
'ic_number' => Yii::t('user', 'Ic Number'),
'auth_key' => Yii::t('user', 'Auth Key'),
'status' => Yii::t('user', 'Status'),
'created_at' => Yii::t('user', 'Created At'),
'updated_at' => Yii::t('user', 'Updated At'),
'company_id' => Yii::t('user', 'Company'),
'branch_id' => Yii::t('user', 'Branch'),
'edu_level' => Yii::t('user', 'Education Level'),
'position_level' => Yii::t('user', 'Position Level'),
'designation' => Yii::t('user', 'Designation'),
'get_mail' => Yii::t('user', 'Get Mail'),
'date_joined' => Yii::t('user', 'Date Joined'),
'gender' => Yii::t('user', 'Gender'),
'address1' => Yii::t('user', 'Address1'),
'address2' => Yii::t('user', 'Address2'),
'address3' => Yii::t('user', 'Address3'),
'address4' => Yii::t('user', 'Address4'),
'country' => Yii::t('user', 'Country'),
'state' => Yii::t('user', 'State'),
'city' => Yii::t('user', 'City'),
'postcode' => Yii::t('user', 'Postcode'),
'tel_no' => Yii::t('user', 'Tel No'),
'marital_status' => Yii::t('user', 'Marital Status'),
'child_no' => Yii::t('user', 'Child No'),
'race' => Yii::t('user', 'Race'),
'religion' => Yii::t('user', 'Religion'),
'resident_status' => Yii::t('user', 'Resident Status'),
'bumi_status' => Yii::t('user', 'Bumi Status'),
];
}
public static function find()
{
return new UserQuery(get_called_class());
}
public function getCountries()
{
return $this->hasOne(Countries::classname(),['id'=>'country']);
}
public function getStates()
{
return $this->hasOne(States::classname(),['id'=>'state']);
}
public function getNext_of_kin()
{
return $this->hasMany(NextOfKin::classname(),['staff_id'=>'staff_id']);
}
}
This is my view controller
public function actionView($staff_id)
{
$request = Yii::$app->request;
$model = $this->findModel($staff_id);
$model2 = $model ->next_of_kin;
//$sql = "SELECT next_of_kin.name AS Name FROM user left join next_of_kin ON next_of_kin.staff_id = user.staff_id";
$dataProvider = new ActiveDataProvider([
'query' => User::find() ->joinWith(['next_of_kin'])-> where(['next_of_kin.staff_id' => $staff_id]),
]);
if($request->isAjax)
{
Yii::$app->response->format = Response::FORMAT_JSON;
return [
'title'=> "User #".$staff_id,
'content'=>$this->renderAjax('view', [
'model' => $model,
'dataProvider' => $dataProvider,
]),
'footer'=> Html::button('Close',['class'=>'btn btn-default pull-left','data-dismiss'=>"modal"]).
Html::a('Edit',['update','staff_id'=>$staff_id],['class'=>'btn btn-primary','role'=>'modal-remote'])
];
}
else
{
return $this->render('view', [
'model' => $model,
'dataProvider' => $dataProvider,
"size" => "modal-lg",
]);
}
}
This is the view file
[
'label' => 'Next of Kin Details',
'content' => GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'username',
'fullname',
'staff_id',
'next_of_kin.name',
],
]),
],
I trying to get the name from table next_of_kin based on the staff id inside the User table. But it keep show not set when I try to view it

Why use array when you want to join with a single table/relation, I mean it shouldn't be wrong, but it's confusing.
Your query doesn't seem wrong, look for the Database module of the debugger to see what the actual query Yii AR composed and run it in the DB in a raw form. The query itself is not broken, at least from what I can tell, DB architecture, the fact that you can query for a staff_id that has nothing to return, the way you pass $staff_id and several other stuff could be broken.

activeDataProvider return a collection of models
you can retrieve an array of model from dataProvider
$myModels = $dataProvider->getModels();
eg: get the first element(user model) next_of_kin models
$my_next_of_kin = $myModels[0]->next_of_kin;
iterate over models for get a value;
foreach ($my_next_of_kin as $key => $value) {
echo $value->your_next_of_kin_col;
}

It works only with one-to-one relations! You have one-to-many.
public function getNext_of_kin()
{
return $this->hasMany(NextOfKin::classname(),['staff_id'=>'staff_id']);
}
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'username',
'fullname',
'staff_id',
'next_of_kin.name', // "next_of_kin" should be one-to-one relation
],

Related

Yii2: Add data picker for gridview

I have output code for certain data from related tables. but I also have the task to add 2 search fields by date.
There should be 2 fields created_at and end_at choosing the date in which I would be able to filter out the extra data
my Controller:
{
$dateNowMinusMonth = new \DateTime('-1 month');
$payed = OrderPayment::find()->where(['status' => OrderPayment::STATUS_PAYED])
->andWhere(['>=', 'created_at', $dateNowMinusMonth->format('Y-m-d H:i:s')])
->all();
$orderIds = ArrayHelper::getColumn($payed, 'order_id');
$elements = [];
if ($orders = Order::find()->where(['id' => $orderIds])->all()) {
foreach ($orders as $order) {
foreach ($order->elements as $element) {
$product = $element->product;
if (array_key_exists($product->id, $elements)) {
$elements[$product->id]['count'] += 1;
} else {
$elements[$product->id] = [
'name' => $product->name,
'barcode' => $product->barcode,
'count' => 0,
'amount' => $product->storitem->amount,
'item_cost' => $product->purchase->item_cost,
'price' => $product->price,
];
}
}
}
}
$dataProvider = new ArrayDataProvider([
'allModels' => $elements,
'sort' => [
'defaultOrder' => ['count' => SORT_DESC],
'attributes' => ['name', 'count', 'barcode', 'amount', 'item_cost', 'price']
],
'pagination' => [
'pageSize' => 15,
],
]);
return $this->render('Reporat', [
'dataProvider' => $dataProvider,
]);
}
and view:
<?= GridView::widget([
'id' => 'search-table',
'dataProvider' => $dataProvider,
'striped' => false,
'options' => ['class' => 'text-center'],
'columns' => [
'name',
'barcode',
'item_cost',
'price',
'count',
'amount'
],
]); ?>
Please help me add 2 fields by which I would be able to filter the displayed data by date of creation and end date.

Toggle user confirmation not working

I am working on an application with user platform shown below:
Controller
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
public function actionIndex()
{
$searchModel = new UserSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Model
public function attributeLabels()
{
return [
'user_id' => Yii::t('app', 'User ID'),
'user_login_id' => Yii::t('app', 'User Login ID'),
'user_password' => Yii::t('app', 'Password'),
'user_type' => Yii::t('app', 'User Type'),
'is_block' => Yii::t('app', 'Block Status'),
'is_confirmed' => Yii::t('app', 'Block Status'),
'confirmed_at' => Yii::t('app', 'Date Confirmed'),
'created_at' => Yii::t('app', 'Created At'),
'created_by' => Yii::t('app', 'Created By'),
'updated_at' => Yii::t('app', 'Updated At'),
'updated_by' => Yii::t('app', 'Updated By'),
'current_pass' => Yii::t('app','Current Password'),
'new_pass' => Yii::t('app','New Password'),
'retype_pass' => Yii::t('app', 'Retype Password'),
'admin_user' => Yii::t('app', 'Admin Username'),
'create_password' => Yii::t('app', 'Password'),
'confirm_password' => Yii::t('app', 'Confirm Password'),
];
}
View
<?php Pjax::begin() ?>
<div class="box box-primary">
<div class="box-body">
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'layout' => "{items}\n{pager}",
'columns' => [
'user_login_id',
'user_type',
[
'attribute' => 'created_at',
'value' => function ($data) {
return (!empty($data->created_at) ? Yii::$app->formatter->asDate($data->created_at) : ' - ');
},
],
[
'header' => Yii::t('urights', 'Confirmation'),
'value' => function ($model) {
if (!$model->is_confirmed) {
return '<div class="text-center"><span class="text-success">' . Yii::t('urights', 'Confirmed') . '</span></div>';
} else {
return Html::a(Yii::t('urights', 'Confirm'), ['confirm', 'id' => $model->user_id], [
'class' => 'btn btn-xs btn-success btn-block',
'data-method' => 'post',
'data-confirm' => Yii::t('urights', 'Are you sure you want to confirm this user?'),
]);
}
},
'format' => 'raw',
],
[
'header' => Yii::t('urights', 'Block status'),
'value' => function ($model) {
if ($model->is_block) {
return Html::a(Yii::t('urights', 'Unblock'), ['block', 'id' => $model->user_id], [
'class' => 'btn btn-xs btn-success btn-block',
'data-method' => 'post',
'data-confirm' => Yii::t('urights', 'Are you sure you want to unblock this user?'),
]);
} else {
return Html::a(Yii::t('urights', 'Block'), ['block', 'id' => $model->user_id], [
'class' => 'btn btn-xs btn-danger btn-block',
'data-method' => 'post',
'data-confirm' => Yii::t('urights', 'Are you sure you want to block this user?'),
]);
}
},
'format' => 'raw',
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
],
],
]);
?>
</div>
</div>
<?php Pjax::end() ?>
As shown in the diagram, when I click on Confirm (Green Button), it shown disable the button and turn it to Confirmed. Then set is_confimred to 0 (zero).
Also, if I click on Block (Red Button), it should change the button caption to unblock and set is_block to 0.
However, I am not getting result, but I have the page shown below:
How do I resolve it?
You should add toggle functions for both confirm and block to the controller.
public function actionConfirm($id)
{
if(($model = User::findOne($id)) !== null) {
$model->is_confirmed = $model->is_confirmed ? false : true;
$model->update();
}
return $this->redirect(['index']);
}
public function actionBlock($id)
{
if(($model = User::findOne($id)) !== null) {
$model->is_block = $model->is_block ? false : true;
$model->update();
}
return $this->redirect(['index']);
}

Display gridview based on user login in yii2

How to display gridview based on current user login at index? For example, student A login and fill the form and logout. When other student login, the data that has been filled by student A will not display.
At gridview
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'education_id',
'year',
'fieldstudy',
'institute',
'grade',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
At controller
public function actionIndex()
{
$dataProvider = new ActiveDataProvider([
'query' => Education::find()->
where(['user_id' => Yii::$app->user->identity->id ]),
]);
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
}
At model
class Education extends ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return 'education';
}
public function rules()
{
return [
[['year', 'fieldstudy', 'institute', 'grade'], 'required'],
[['user_id'], 'integer'],
[['year', 'fieldstudy', 'institute', 'grade'], 'string', 'max' => 255],
];
}
public function attributeLabels()
{
return [
'education_id' => 'Education ID',
'student_id' => 'Student ID',
'year' => 'Year',
'fieldstudy' => 'Fieldstudy',
'institute' => 'Institute',
'grade' => 'Grade',
];
}
public function getId($id)
{
return static::find(['user_id' => $id]);
}
If you need retrive the Education info related to an user id and assuming that in the Education model this relation is based on the field user_id you could use Yii::$app->user->identity->id
$dataProvider = new ActiveDataProvider([
'query' => Education::find()->
where(['user_id' => Yii::$app->user->identity->id ]),
]);

Call to a member function saveAs() on null (I can not update if I do not select an image)

I can not update if I do not select an image. What do wrong or I'm missing?
This is a controller:
if ($model->load(Yii::$app->request->post())) {
$nameImage=$model->name;
$model->bookimg=UploadedFile::getInstance($model,'bookimg');
$model->bookimg->saveAs('images/'.$nameImage.'.'.$model->bookimg->extension);
$model->bookimg='images/'.$nameImage.'.'.$model->bookimg->extension;
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
This is a model:
[['fkperiodo'], 'integer'],
[['date_public'], 'safe'],
[['name'], 'string', 'max' => 100],
[['volume'], 'string', 'max' => 5],
[['author',], 'string', 'max' => 255],
[['bookimg'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
[['fkperiod'], 'exist', 'skipOnError' => true, 'targetClass' => Period::className(), 'targetAttribute' => ['fkperiod' => 'id']],
This is a form:
<?= $form->field($model, 'bookimg')->fileInput()->label('Book Cover') ?>
You have to check if $model to be updated had already an image and react accordingly if user has chosen a new image.
Example
if ($model->load(Yii::$app->request->post())) {
$nameImage = $model->name;
$old_image = $model->bookimg;
$model->bookimg = UploadedFile::getInstance($model, 'bookimg');
//If user has chosen an image
if (!empty($model->bookimg)) {
if (!empty($old_image)) {
//Delete old image from filesystem or/and database
//...
//...
}
//Save the new image
$model->bookimg->saveAs('images/'.$nameImage.'.'.$model->bookimg->extension);
$model->bookimg = 'images/'.$nameImage.'.'.$model->bookimg->extension;
}
//Also consider checking if model has been successfully saved before redirect
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}

Yii2 : Cannot Show Data in Widget GridView

I try to show data from database in view using gridview, but i got problem
error message
Unknown Method – yii\base\UnknownMethodException
Calling unknown method: yii\db\ActiveQuery::getCount()
my controller
public function actionIndex()
{
$sql = "SELECT presensi.presensi_tanggal 'tanggal', sum(if( hadir.keteranganhadir_id='1',1,0)) 'hadir', sum(if( hadir.keteranganhadir_id='2',1,0)) 'tidak_hadir', count(*) 'total' FROM hadir, keteranganhadir, presensi where hadir.keteranganhadir_id = keteranganhadir.keteranganhadir_id and hadir.presensi_id = presensi.presensi_id group by presensi.presensi_tanggal";
$model = Hadir::findBySql($sql)->all();
return $this->render('index', [
'hadir' => $model,
]);
}
my view
<?= GridView::widget([
'dataProvider' => $hadir,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'tanggal',
'hadir',
'tidak_hadir',
'total',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
How can i fix the problem?
Gridview looks for dataprovider, not array of activerecord models you have sent:
http://www.yiiframework.com/doc-2.0/yii-data-sqldataprovider.html
in your controller/actionIndex
$count = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM user WHERE status=:status
', [':status' => 1])->queryScalar();
$dataProvider = new SqlDataProvider([
'sql' => 'SELECT * FROM user WHERE status=:status',
'params' => [':status' => 1],
'totalCount' => $count,
'sort' => [
'attributes' => [
'age',
'name' => [
'asc' => ['first_name' => SORT_ASC, 'last_name' => SORT_ASC],
'desc' => ['first_name' => SORT_DESC, 'last_name' => SORT_DESC],
'default' => SORT_DESC,
'label' => 'Name',
],
],
],
'pagination' => [
'pageSize' => 20,
],
]);
return $this->render('index', [
'hadir' => $dataProvider,
]);
You can try this:
In Controller.php file:
public function actionIndex()
{
$searchModel = new InvoiceSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Your view file seems to be true. Just add above code in your controller file.