how to call background function from web controller in yii2 - php

I have a controller function that save some file in DB and then create personal PDF file for every record in DB and email it to him . The problem is that it take to much time. Can I call console controller from the web controller function and pass the id to the console function? Or there is a better or other method to do this?

I don't think calling console command from web controller will help too much.
But for this purpose you can use for example this extension.
Usage:
Imported class:
use vova07\console\ConsoleRunner;
$cr = new ConsoleRunner(['file' => '#my/path/to/yii']);
$cr->run('controller/action param1 param2 ...');
Application component:
// config.php
...
components [
'consoleRunner' => [
'class' => 'vova07\console\ConsoleRunner',
'file' => '#my/path/to/yii' // or an absolute path to console file
]
]
...
// some-file.php
Yii::$app->consoleRunner->run('controller/action param1 param2 ...');
But I recommend to use work queues for that like RabbitMQ or Beanstalkd, these are more suitable for your task.

I think is better you use a proper class with proper function/metohd , share this in common area and invoke the function in the different controllers
common model
namespace common\models;
use Yii;
/**
* This is the model class for table "c2_common_user_param".
*
* #property integer $id
* #property integer $user_id
* #property string $land_scope_code
* #property string $init_lat
* #property string $init_lng
* #property integer $init_zoom
* #property string $google_maps_api_key
*
* #property DfenxUser $user
*/
class UserParam extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'c2_common_user_param';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['user_id'], 'required'],
[['user_id', 'init_zoom'], 'integer'],
[['init_lat', 'init_lng'], 'number'],
[['land_scope_code'], 'string', 'max' => 4],
[['google_maps_api_key'], 'string', 'max' => 255]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'user_id' => Yii::t('app', 'User ID'),
'land_scope_code' => Yii::t('app', 'Land Scope Code'),
'init_lat' => Yii::t('app', 'Init Lat'),
'init_lng' => Yii::t('app', 'Init Lng'),
'init_zoom' => Yii::t('app', 'Init Zoom'),
'google_maps_api_key' => Yii::t('app', 'Google Maps Api Key'),
];
}
}
backend controller
<?php
namespace backend\controllers;
use Yii;
use common\models\UserParam;
use common\models\UserParamSearch;
use common\models\User;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* UserParamController implements the CRUD actions for UserParam model.
*/
class UserParamController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
/**
* Lists all UserParam models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new UserParamSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
}
frontend controller
<?php
namespace frontend\controllers;
use Yii;
use common\models\UserParam;
use common\models\UserParamSearch;
use common\models\User;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* UserParamController implements the CRUD actions for UserParam model.
*/
class UserParamController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
/**
* Lists all UserParam models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new UserParamSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
}

Related

Yii2 tagging 2amigos is not saving tags to the table

I am trying to implement tagged articles for my new small CMS written with yii2.
This is what i have tried https://forum.yiiframework.com/t/how-to-create-tags-for-posts-in-yii2/123890
Everything is working the tagging machanism is fetching data from the tag table but it is not saving data to the table tag_assign.
This is my form.
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
//Using for Wysiwig editor
use dosamigos\ckeditor\CKEditor;
//Using for Tagging
use dosamigos\selectize\SelectizeTextInput;
/* #var $this yii\web\View */
/* #var $model common\models\Articles */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="articles-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'content')->widget(CKEditor::className(), [
'options' => ['height' => 800],
'preset' => 'basic',
'clientOptions' => ['height' => 400]
]) ?>
<?= $form->field($model, 'tags')->widget(SelectizeTextInput::className(), [
// calls an action that returns a JSON object with matched
// tags
'loadUrl' => ['tag/list'],
'options' => ['class' => 'form-control'],
'clientOptions' => [
'plugins' => ['remove_button'],
'valueField' => 'name',
'labelField' => 'name',
'searchField' => ['name'],
'create' => true,
],
])->hint('Use commas to separate tags') ?>
<?= $form->field($model, 'date')->textInput() ?>
<div class="form-group">
<?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
And this is my tag model
<?php
namespace common\models;
use Yii;
use dosamigos\taggable\Taggable;
/**
* This is the model class for table "tags".
*
* #property int $id
* #property string $frequency
* #property string $name
*/
class Tag extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'tags';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['frequency', 'name'], 'required'],
[['frequency'], 'string', 'max' => 500],
[['name'], 'string', 'max' => 250],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'frequency' => 'Frequency',
'name' => 'Name',
];
}
//For Tagging
public function behaviors() {
return [
[
'class' => Taggable::className(),
],
];
}
public function findAllByName($name)
{
return Tag::find()->where('name LIKE :query')
->addParams([':query'=>"%$name%"])
->all();
}
}
Tag controller.
<?php
namespace backend\controllers;
use Yii;
use common\models\Tag;
use common\models\searchTag;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\Response;
/**
* TagController implements the CRUD actions for Tag model.
*/
class TagController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Tag models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new searchTag();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Tag model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Tag model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Tag();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('create', [
'model' => $model,
]);
}
public function actionList($query)
{
$models = Tag::findAllByName($query);
$items = [];
foreach ($models as $model) {
$items[] = ['name' => $model->name];
}
// We know we can use ContentNegotiator filter
// this way is easier to show you here :)
Yii::$app->response->format = Response::FORMAT_JSON;
return $items;
}
/**
* Updates an existing Tag model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
/**
* Deletes an existing Tag model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Tag model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Tag the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Tag::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
}
And the articles
<?php
namespace common\models;
use Yii;
//For Taggable
use dosamigos\taggable\Taggable;
/**
* This is the model class for table "articles".
*
* #property int $id
* #property string $title
* #property string $content
* #property string $tags
* #property string $date
*/
class Articles extends \yii\db\ActiveRecord
{
//For taggable
public function behaviors() {
return [
[
'class' => Taggable::className(),
],
];
}
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'articles';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['title', 'content', 'tags', 'date'], 'required'],
[['content'], 'string'],
[['date'], 'safe'],
[['title', 'tags'], 'string', 'max' => 250],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'content' => 'Content',
'tags' => 'Tags',
'date' => 'Date',
];
}
public function getTags()
{
return $this->hasMany(Tag::className(), ['id' => 'tag_id'])->viaTable('tag_assign', ['article_id' => 'id']);
}
}
What I am missing? How can I trouble shoot at least what is going wrong?

searching not work in yii2

I want to do search in Nama Mahasiswa search bar like picture below. As example I type name yuhara but there are no result whereas there are yuhara in the database.
Search model codes:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\AlumnyS3;
use app\models\AlumniIntegrasi;
/**
* AlumnyS3Search represents the model behind the search form about `app\models\AlumnyS3`.
*/
class AlumnyS3Search extends AlumnyS3
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['Alumnys3ID'], 'integer'],
[['NRP', 'NamaMahasiswa', 'ProgramStudi', 'TanggalMasuk', 'TanggalKeluar'], 'safe'],
];
}
public $NamaMahasiswa;
/*public $TanggalMasuk;
public $tanggalMasukText;*/
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = AlumnyS3::find();
$query->joinWith('alumniIntegrasi');
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$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([
'Alumnys3ID' => $this->Alumnys3ID,
]);
$query->andFilterWhere([
'alumnys3.NRP' => $this->NRP,
'alumniintegrasi.NamaMahasiswa' => $this->NamaMahasiswa,
'alumnys3.ProgramStudi' => $this->ProgramStudi,
'alumnys3.TanggalMasuk' => $this->TanggalMasuk,
'alumnys3.TanggaKeluar' => $this->TanggalKeluar
]);
return $dataProvider;
}
}
Model codes:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "alumnys3".
*
* #property integer $Alumnys3ID
* #property string $NRP
* #property string $ProgramStudi
* #property string $TanggalMasuk
* #property string $TanggalKeluar
*
* #property AlumniIntegrasi $nRP
*/
class AlumnyS3 extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'alumnys3';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['NRP'], 'required'],
[['NRP'], 'string', 'max' => 15],
[['ProgramStudi'], 'string', 'max' => 5],
[['TanggalMasuk', 'TanggalKeluar'], 'string', 'max' => 30],
[['NRP'], 'exist', 'skipOnError' => true, 'targetClass' => AlumniIntegrasi::className(), 'targetAttribute' => ['NRP' => 'NRP']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'Alumnys3ID' => Yii::t('app', 'Alumnys3 ID'),
'NRP' => Yii::t('app', 'Nrp'),
'ProgramStudi' => Yii::t('app', 'Program Studi'),
'TanggalMasuk' => Yii::t('app', 'Tanggal Masuk'),
'TanggalKeluar' => Yii::t('app', 'Tanggal Keluar'),
'NamaMahasiswa' => Yii::t('app', 'Nama Mahasiswa'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getalumniIntegrasi()
{
return $this->hasOne(alumniIntegrasi::className(), ['NRP' => 'NRP']);
}
public function getNamaMahasiswa()
{
$alumniIntegrasi = alumniIntegrasi::findOne(['NRP'=> $this->NRP]);
if (empty($alumniIntegrasi))
return '';
return $alumniIntegrasi->NamaMahasiswa;
}
/*public function getTanggalMasukText()
{
$alumniIntegrasi = alumniIntegrasi::findOne(['NRP'=> $this->NRP]);
if (empty($alumniIntegrasi))
return '';
return $alumniIntegrasi->TanggalMasuk;
}*/
}
Index codes:
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\AlumnyS3Search */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Alumny S3s');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="alumny-s3-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a(Yii::t('app', 'Create Alumny S3'), ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'Alumnys3ID',
'NRP',
'NamaMahasiswa',
'ProgramStudi',
//'tanggalMasukText',
'TanggalMasuk',
'TanggalKeluar',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
I don't know how to fix that. Could you plese help me to solve this codes? I'm really grateful if you can solve this, thanks!
Add like query in search model like below
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\AlumnyS3;
use app\models\AlumniIntegrasi;
/**
* AlumnyS3Search represents the model behind the search form about `app\models\AlumnyS3`.
*/
class AlumnyS3Search extends AlumnyS3
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['Alumnys3ID'], 'integer'],
[['NRP', 'NamaMahasiswa', 'ProgramStudi', 'TanggalMasuk', 'TanggalKeluar'], 'safe'],
];
}
public $NamaMahasiswa;
/*public $TanggalMasuk;
public $tanggalMasukText;*/
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = AlumnyS3::find();
$query->joinWith('alumniIntegrasi');
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$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([
'Alumnys3ID' => $this->Alumnys3ID,
]);
$query->andFilterWhere([
'alumnys3.NRP' => $this->NRP,
// 'alumniintegrasi.NamaMahasiswa' => $this->NamaMahasiswa,
'alumnys3.ProgramStudi' => $this->ProgramStudi,
'alumnys3.TanggalMasuk' => $this->TanggalMasuk,
'alumnys3.TanggaKeluar' => $this->TanggalKeluar
]);
$query->andFilterWhere(['like', 'alumniintegrasi.NamaMahasiswa', $this->NamaMahasiswa]);
return $dataProvider;
}
}

Yii2 query result always returns the same

I am working on a Yii2 based project right now. Today when I was testing my application I noticed a very interesting bug in it. I have a Products table with it's model and controllers and views. (These are generated with gii)
When I list all the records in the index action it works fine. But here comes the bug. When I click on the edit or view action it alwasy renders the first record in the database. I was var_dump the result of the queries and always returnd the mentiond result. Only when I used createCommand got the proper result.
What do you think guys could be the problem with it?
The controller
<?php
namespace backend\controllers;
use Yii;
use app\models\Termek;
use yii\data\ActiveDataProvider;
use yii\db\Query;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* TermekController implements the CRUD actions for Termek model.
*/
class TermekController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Termek models.
* #return mixed
*/
public function actionIndex()
{
$dataProvider = new ActiveDataProvider([
'query' => Termek::find(),
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Termek model.
* #param integer $id
* #return mixed
*/
public function actionView($id)
{
$model = $this->findModel($id);
return $this->render('view', [
'model' => $model,
]);
}
/**
* Creates a new Termek model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Termek();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
/**
* Updates an existing Termek model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Termek model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Termek model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Termek the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Termek::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
The index.php view file
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('app', 'Termeks');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="termek-index">
<h1><?= Html::encode($this->title) ?></h1>
<p>
<?= Html::a(Yii::t('app', 'Create Termek'), ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'nev',
'szelesseg',
'magassag',
'egyeb:ntext',
// 'ar',
// 'termek_kategoria_id',
// 'torolt',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
Part of view.php view file:
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'nev',
'szelesseg',
'magassag',
'egyeb:ntext',
'ar',
'termek_kategoria_id',
'torolt',
],
]) ?>
Model file:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "termek".
*
* #property integer $id
* #property string $nev
* #property double $szelesseg
* #property double $magassag
* #property string $egyeb
* #property string $ar
* #property integer $termek_kategoria_id
* #property string $torolt
*/
class Termek extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'termek';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['nev', 'termek_kategoria_id'], 'required'],
[['szelesseg', 'magassag'], 'number'],
[['egyeb'], 'string'],
[['ar', 'termek_kategoria_id'], 'integer'],
[['torolt'], 'safe'],
[['nev'], 'string', 'max' => 255],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'nev' => Yii::t('app', 'Nev'),
'szelesseg' => Yii::t('app', 'Szelesseg'),
'magassag' => Yii::t('app', 'Magassag'),
'egyeb' => Yii::t('app', 'Egyeb'),
'ar' => Yii::t('app', 'Ar'),
'termek_kategoria_id' => Yii::t('app', 'Termek Kategoria ID'),
'torolt' => Yii::t('app', 'Torolt'),
];
}
/**
* #inheritdoc
* #return \app\models\Query\TermekQuery the active query used by this AR class.
*/
public static function find()
{
return new \app\models\Query\TermekQuery(get_called_class());
}
}
Try modify the findModel function using find()->where instead of findOne
protected function findModel($id)
{
var_dump($id);
$model = Termek::find()->where(['id'=> $id])->one();
var_dump($model);
if (($model !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
I am not sure why but somehow the error solved. I had a function in TermekQuery that was supposed to query all the records that has the deleted field null. I removed it and now works fine.

How to show relational data in yii2

I'm having trouble understanding how relations work in yii 2
I have 2 tables in a mysql database, author and book.
book has a column named author which links to the id of the author table via foreign key.
I've generated CRUD using gii, and I want the author name to appear in the list view, as well as dropdowns for the author name in the create and update views.
But I cant seem to get the relation working even in the list view.
Here's my code
Book Model:
<?php
namespace app\models;
use Yii;
use app\models\Author;
/**
* This is the model class for table "book".
*
* #property integer $id
* #property string $name
* #property integer $author
*/
class Book extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'book';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name', 'author'], 'required'],
[['author'], 'integer'],
[['name'], 'string', 'max' => 11]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
'author' => 'Author',
];
}
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author']);
}
}
BookSearch Model:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Book;
/**
* BookSearch represents the model behind the search form about `app\models\Book`.
*/
class BookSearch extends Book
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'author'], 'integer'],
[['name'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Book::find();
$query->joinWith('author');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
var_dump($dataProvider);
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;
}
$query->andFilterWhere([
'id' => $this->id,
'author' => $this->author,
]);
$query->andFilterWhere(['like', 'name', $this->name]);
return $dataProvider;
}
}
Also, here's the view file:
<?php
use yii\helpers\Html;
use yii\grid\GridView;
/* #var $this yii\web\View */
/* #var $searchModel app\models\BookSearch */
/* #var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Books';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="book-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php // echo $this->render('_search', ['model' => $searchModel]); ?>
<p>
<?= Html::a('Create Book', ['create'], ['class' => 'btn btn-success']) ?>
</p>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'name',
[
'attribute' => 'author',
'value' => 'author.name',
],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
</div>
Author Model:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "author".
*
* #property integer $id
* #property string $name
*/
class Author extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'author';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['name'], 'required'],
[['name'], 'string', 'max' => 200]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
];
}
}
I think I may have to change something somehwhere in the author/authorSearch model.
Can someone help
thanks
You can also add columns to a gridview with value from an anonymous function as described here http://www.yiiframework.com/doc-2.0/yii-grid-datacolumn.html#$value-detail. For example you can show an author's name like this in a gridview:
<?= GridView::widget([
'dataProvider'=>$dataProvider,
'filterModel'=>$searchModel,
'columns'=>[
[
'attribute'=>'author.name',
'value'=>function ($model, $key, $index, $column) {
return $model->author->name;
},
],
//...other columns
]);
?>
you can also return a html-link to the detail-view of an author like this:
//...
'columns'=>[
[
'attribute'=>'author',
'value'=>function ($model, $key, $index, $column) {
return Html::a($model->author->name, ['/author/view', 'id'=>$model->author->id]);
},
],
//...
],
//...
You can access relation table data in any crud view file using their relation name. $model->relName->attribute_name.
And You can access relation table data in gridview at following way :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'author',
'value'=>'author.author_name', //relation name with their attribute
]
],
]);
First you need a get function in your model, but you have.
This is :
public function getAuthor()
{
return $this->hasOne(Author::className(), ['id' => 'author']);
}
Now you just need do one more thing.
Go to the index file, and to GridView, and columns.
Write this into columns:
[
'attribute' => 'author',
'value' => 'author.name',
],
In the value, the first parameter is your Get function, what named is : getAuthor, and . after your column name.
Hello in your BookSearch Mode please add below code like this.
$query->joinWith(array('author'));
$query->andFilterWhere(['id' => $this->id,])
->andFilterWhere(['like', 'author.author_name', $this->author]);
And in your view file please use below given code below code is for view file inside grid attrubute.
[
'attribute' => 'author',
'value' => 'author.name',
]
i hope this will helps you. and i hope in author table name is stored in name column.
This worked for me - inside the BookSearch Model:
public function search($params)
{
$dataProvider = new \yii\data\SqlDataProvider([
'sql' => 'SELECT book.id as id ,book.author_fk, book.name as book_name , author.name as author_name' .
' FROM book ' .
'INNER JOIN author ON (book.author_fk = author.id) '
]);
$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;
}
return $dataProvider;
}
Only issue now is getting the ActionColumn to work correctly, they're currently linking to the wrong IDs, help anyone.

Yii2 Search model, Invalid argument supplied for foreach

I am new at Yii framework and I am facing this problem that when i am creating search model to add filters and sorting, it's not working, i already have tried this solution Yii2 ActiveDataProvider - Invalid argument supplied for foreach() and even generated the new models and controller but the result is same, it did not work.
Please have a look at the code and kindly tell me what i am doing wrong.
Controller
namespace backend\controllers;
use Yii;
use backend\models\Contacts;
use backend\models\ContactsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* ContactsController implements the CRUD actions for Contacts model.
*/
class ContactsController extends Controller
{
...
/**
* Lists all Contacts models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new ContactsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider
]);
}
...
}
Model
namespace backend\models;
use Yii;
use backend\models\User;
/**
* This is the model class for table "user_contacts".
*
* #property string $id
* #property string $user_id
* #property string $contact_id
* #property string $created_on
* #property string $modified_on
*
* #property User $contact
* #property User $user
*/
class Contacts extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'user_contacts';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['user_id', 'contact_id'], 'integer'],
[['created_on', 'modified_on'], 'safe'],
[['user_id', 'contact_id'], 'unique', 'targetAttribute' => ['user_id', 'contact_id'], 'message' => 'The combination of User ID and Contact ID has already been taken.']
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'user_id' => Yii::t('app', 'User ID'),
'contact_id' => Yii::t('app', 'Contact ID'),
'created_on' => Yii::t('app', 'Created On'),
'modified_on' => Yii::t('app', 'Modified On')
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getContact()
{
return $this->hasOne(User::className(), ['id' => 'contact_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
/**
* #inheritdoc
* #return ContactsSearch the active query used by this AR class.
*/
public static function find()
{
return new ContactsSearch(get_called_class());
}
}
Search model
namespace backend\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use backend\models\Contacts;
/**
* ContactsSearch represents the model behind the search form about `backend\models\Contacts`.
*/
class ContactsSearch extends Contacts
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'user_id', 'contact_id'], 'integer'],
[['created_on', 'modified_on'], 'safe']
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Contacts::find();
$dataProvider = new ActiveDataProvider([
'query' => $query
]);
$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;
}
$query->andFilterWhere([
'id' => $this->id,
'user_id' => $this->user_id,
'contact_id' => $this->contact_id,
'created_on' => $this->created_on,
'modified_on' => $this->modified_on
]);
return $dataProvider;
}
}
View(index.php)
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'user_id',
'contact_id',
'created_on',
'modified_on',
['class' => 'yii\grid\ActionColumn']
]
]);
Error
PHP Warning – yii\base\ErrorException
Invalid argument supplied for foreach()
1. in F:\Files\Web\PHP\wamp\www\Php\sites\expenses\vendor\yiisoft\yii2\BaseYii.php at line 517
public static function configure($object, $properties)
{
foreach ($properties as $name => $value) {
$object->$name = $value;
}
return $object;
}
2. in F:\Files\Web\PHP\wamp\www\Php\sites\expenses\backend\models\Contacts.php at line 76 – yii\base\Object::__construct()
public static function find()
{
return new ContactsSearch(get_called_class());
}
3. in F:\Files\Web\PHP\wamp\www\Php\sites\expenses\backend\models\ContactsSearch.php at line 43 – backend\models\Contacts::find()
public function search($params)
{
$query = Contacts::find();
$dataProvider = new ActiveDataProvider([
'query' => $query
]);
$this->load($params);
...

Categories