I have to implementing export excel using moonland PHP excel extension. When I implemented it, it throws the error:
"Call to a member function getAttributeLabel() on null".
Code
$dataProvider = new \app\models\Details;
\moonland\phpexcel\Excel::widget([
'models' => $dataProvider,
'mode' => 'export', //default value as 'export'
'columns' => ['id','name','address'], //without header working, because the header will be get label from attribute label.
//'header' => ['id' => 'Header Column 1','name' => 'Header Column 2', 'address' => 'Header Column 3'],
]);
My model
class Details extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'details';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id'], 'required'],
[['id'], 'integer'],
[['name', 'address'], 'string', 'max' => 50],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
/* return [
'id' => Yii::t('app', 'ID'),
'name' => Yii::t('app', 'Name'),
'address' => Yii::t('app', 'Address'),
];*/
return [
'id' => 'ID',
'name' => 'Name',
'address' =>'Address',
];
}
}
Table
May i know what is the problem in that, thanks in advance for your idea
Related
The connection between the modules does not work, and because of this, the data in the table is not displayed. I can not understand why
Code in the controller
public function actionIndex()
{
$searchModel = new SuggestedNewsSearch();
$dataProvider = $searchModel->getAllNews(Yii::$app->request->queryParams);
return $this->render('index', [
'dataProvider' => $dataProvider,
'searchModel' => $searchModel
]);
}
code in suggestedNewsSearch.php
class SuggestedNewsSearch extends SuggestedNews
{
public function getAllNews($params)
{
$query = $this::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if ($this->validate() AND !($this->load($params))) {
return $dataProvider;
}
if (!empty($this->getAttribute('title'))) {
$query->andFilterWhere(['LIKE', 'title', $this->getAttribute('title')]);
}
if (!empty($this->getAttribute('category'))) {
$query->andFilterWhere(['LIKE', 'category', $this->getAttribute('category')]);
}
if (!empty($this->getAttribute('status'))) {
switch (mb_strtolower($this->getAttribute('status'))) {
case $this::APPROVED:
$status = $this::ACTIVE_STATUS;
break;
case $this::NOT_APPROVED:
$status = $this::DEACTIVATED_STATUS;
break;
}
$query->andFilterWhere(['=', 'status', $status]);
}
return $dataProvider;
}
}
code on SuggestedNews.php
class SuggestedNews extends \yii\db\ActiveRecord
{
CONST ACTIVE_NEWS = 1;
CONST ACTIVE_STATUS = 1;
CONST DEACTIVATED_STATUS = 0;
CONST APPROVED = 'одобренно';
CONST NOT_APPROVED = 'не одобренно';
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'suggested_news';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['news'], 'string'],
[['category', 'status'], 'integer'],
[['date'], 'safe'],
[['title', 'news_source'], 'string', 'max' => 255],
[['category'], 'exist', 'skipOnError' => true, 'targetClass' => Category::className(), 'targetAttribute' => ['category' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'title' => 'Title',
'news' => 'News',
'category' => 'Category',
'status' => 'Status',
'date' => 'Date',
'news_source' => 'News Source',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Category::className(), ['id' => 'category']);
}
public function deleteNewsById($id)
{
$customer = $this::findOne($id);
if ($customer->delete()) return true;
else return false;
}
public function getNewsByIdWithCategory($id){
return $this::find()->where(['id' => $id])->with('category')->one();
}
}
code on Category.php
class Category extends \yii\db\ActiveRecord
{
CONST STATUS_CATEGORY_OFF = 0;
CONST STATUS_CATEGORY_ON = 1;
CONST NEW_CATEGORY_INTEGER = 01;
CONST NEW_CATEGORY_NAME = 'New Category';
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'category';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['name', 'status_category'], 'required'],
[['status_category'], 'integer'],
[['name'], 'string', 'max' => 255],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
'status_category' => 'Status Category',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getSuggestedNews()
{
return $this->hasMany(SuggestedNews::className(), ['category' => 'id']);
}
public function getAllCategories(){
return $this::find()->where(['status_category' => $this::STATUS_CATEGORY_ON])->all();
}
}
my index.php file(view)
<?php echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
[
'attribute' => 'title',
'format' => 'text',
'label' => 'title',
'filter' => true,
],
[
'attribute' => 'category.Category',
'format' => 'text',
'label' => 'Category',
],
[
'attribute' => 'status',
'filter' => true,
'value' => function($model) {
if($model->status == 1){
return $model::APPROVED;
}else{
return $model::NOT_APPROVED;
}
}
],
'date',
[
'class' => 'yii\grid\ActionColumn',
],
],
]);
?>
and on result i have this:result table
enter image description here
table category
table suggested_news
You field name and relation are the same, so You have to change Category relation name like this:
/**
* #return \yii\db\ActiveQuery
*/
public function getCategory1()
{
return $this->hasOne(Category::className(), ['id' => 'category']);
}
//Gridview
//...
[
'attribute' => 'category',
'label' => 'Category',
'value' => function($model){
return $model->category1->name;
}
],
//...
//or
//...
[
'attribute' => 'category1.name',
'format' => 'text',
'label' => 'Category',
],
Hope it will helps.
I have a database having relationship of three levels. cheque->account->customer. Now I am trying to retrieve data from all three table at same time using the following method.
$query = Cheque::find();
$query->joinWith(['account.customer']);
$query->orderBy('sr desc');
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
Cheque Model:
class Cheque extends \common\components\db\ActiveRecord {
/**
* #inheritdoc
*/
public static function tableName() {
return 'cheque';
}
/**
* #inheritdoc
*/
public function rules() {
return [
[['sr'], 'integer'],
[['ID', 'account_ID'], 'required'],
[['ID', 'account_ID', 'created_by', 'branch_ID', 'application_ID'], 'string'],
[['serial_start', 'serial_end', 'status'], 'number'],
[['created_on'], 'safe']
];
}
/**
* #inheritdoc
*/
public function attributeLabels() {
return [
'ID' => 'ID',
'account_ID' => 'Account ID',
'serial_start' => 'Serial Start',
'serial_end' => 'Serial End',
'created_on' => 'Created On',
'created_by' => 'Created By',
'branch_ID' => 'Branch ID',
'application_ID' => 'Application ID',
'status' => 'Status',
'sr' => 'ID'
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getAccount() {
return $this->hasOne(Account::className(), ['ID' => 'account_ID']);
}
public static function getActiveChequeBook($account_ID) {
return Cheque::findAll(['account_ID' => $account_ID, 'status' => array_search('Active', \common\models\Lookup::$cheque_status)]);
}
}
But executing this I get the following error:
pre>Exception 'yii\base\InvalidCallException' with message 'Setting read-only property: common\models\Account::customer'
Property customer in your common\models\Account model has no setter (only getCustomer method exists). Check you model and add appropriate property to class.
I have a table called menusoffered where I am storing menuname based on restaurantid which is a foreign key.
In my menusoffered model I have declared that menuname has a unique validator, but this is checking the uniqueness from the entire table.
I want it to check uniqueness based on restaurantid,
Can any one help me how to make this menuname unique for particular restaurantid?
Below is my given menu model,
class Menusoffered extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'menusoffered';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
['phase_id', 'required', 'message' => 'Please select Phase'],
['menuname', 'required'],
['price', 'required'],
[['price'],'integer' , 'message' =>'Price should be in digits'],
[['image_url'], 'file'],
[['description', 'status'], 'string'],
[['createdts','restaurantid'], 'safe'],
['master_menu_sepcality_id', 'required', 'message' => 'Please select Speciality'],
['master_menu_type_id', 'required', 'message' => 'Please select Type'],
['menuname', 'unique', 'with'=>'restaurantid'],
[['restaurantid'], 'exist', 'skipOnError' => true, 'targetClass' => Restaurant::className(), 'targetAttribute' => ['restaurantid' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'master_menu_sepcality_id' => 'Master Menu Sepcality ID',
'master_menu_type_id' => 'Master Menu Type ID',
'item' => 'Item',
'price' => 'Price',
'restaurantid' => 'Restaurantid',
'phase_id' => 'Phase ID',
'description' => 'Description',
'image_url' => 'Image Url',
'status' => 'Status',
'createdts' => 'Createdts',
];
} }
Try this: Yii2 Unique Validator:
// a1 and a2 need to be unique together, only a1 will receive error message
['a1', 'unique', 'targetAttribute' => ['a1', 'a2']]
Am trying to display a grid view in the yii2 view action of a controller but I get an error of Call to a member function getTotalCount() on a non-object
I have two related tables that is table Cases which is related to table Accusers as below
Case Model coe:
public function getAccusers()
{
return $this->hasMany(Accuser::className(), ['case_ref_no' => 'ref_no']);
}
Accusers model relation
public function getCaseRefNo()
{
return $this->hasOne(Cases::className(), ['ref_no' => 'case_ref_no']);
}
In the case controller the action index has a grid view in which I select the view action
In the view action I have passed grid view which basically I would wish that it displays the records of Accusers related to a certain case (That is the case ref no just as in the relationship above)
The case controller code: Action view
public function actionView($id)
{
$dataProvider = Accuser::find()
->where(['case_ref_no'=>$id])
->all();
return $this->render('view', [
'dataProvider' => $dataProvider,
'model' => $this->findModel($id),
]);
}
The view page (code)
use kartik\grid\GridView;
...........
<?= GridView::widget([
'dataProvider' => $dataProvider,
'showPageSummary' =>false,
//'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
I used 'showPageSummary' =>false, but I still get that error of Call to a member function getTotalCount() on a non-object
Full accuser model
class Accuser extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'accuser';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['fname', 'secname', 'date_of_birth', 'case_ref_no', 'idno'], 'required'],
[['date_of_birth'], 'safe'],
[['fname', 'secname', 'case_ref_no', 'idno'], 'string', 'max' => 100]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'fname' => 'Fname',
'secname' => 'Secname',
'date_of_birth' => 'Date Of Birth',
'case_ref_no' => 'Case Ref No',
'idno' => 'Idno',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCaseRefNo()
{
return $this->hasOne(Cases::className(), ['ref_no' => 'case_ref_no']);
}
}
The var_dump($dataProvider); in the view I got(after changing the find()->all() to find() only
object(yii\db\ActiveQuery)[60]
public 'sql' => null
public 'on' => null
public 'joinWith' => null
public 'select' => null
public 'selectOption' => null
public 'distinct' => null
public 'from' => null
public 'groupBy' => null
public 'join' => null
public 'having' => null
public 'union' => null
public 'params' =>
array (size=0)
empty
private '_events' (yii\base\Component) =>
array (size=0)
empty
private '_behaviors' (yii\base\Component) =>
array (size=0)
empty
public 'where' =>
array (size=1)
'case_ref_no' => string '#RERADRADAR' (length=11)
public 'limit' => null
public 'offset' => null
public 'orderBy' => null
public 'indexBy' => null
public 'modelClass' => string 'frontend\models\Accuser' (length=23)
public 'with' => null
public 'asArray' => null
public 'multiple' => null
public 'primaryModel' => null
public 'link' => null
public 'via' => null
public 'inverseOf' => null
For the dataProvider you should create with the proper class (ActiveDataprovider, ArrayDataProvider or SqlDataProvider )
this way and not directly form the query like you have done
$query = Accuser::find()
->where(['case_ref_no'=>$id]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
If you think the problem is related to the summary too you should avoid this using
'summary'=>"",
this way
<?= GridView::widget([
'dataProvider' => $dataProvider,
'summary'=>"",
change your action to this
public function actionView($id)
{
$dataProvider = Accuser::find()
->where(['case_ref_no'=>$id]);
return $this->render('view', [
'dataProvider' => $dataProvider,
'model' => $this->findModel($id),
]);
}
gridview work with dataprovider and find result is your data provider . if you use all() after find your $dataprovider variable is an array of your Accuser object!
This is my model Riders:
<?php
namespace backend\models;
use Yii;
class Riders extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'riders';
}
public function rules()
{
return [
[['cagories_category_id', 'rider_firstname', 'rider_no_tlpn', 'rider_ucinumber', 'countries_id', 'rider_province', 'rider_city', 'rider_dateofbirth', 'rider_gender'], 'required'],
[['user_id', 'countries_id'], 'integer'],
[['rider_dateofbirth', 'cagories_category_id'], 'safe'],
[['rider_gender', 'rider_status'], 'string'],
[['rider_firstname', 'rider_lastname', 'rider_nickname', 'rider_province', 'rider_city'], 'string', 'max' => 45],
[['rider_email', 'rider_sponsor', 'rider_birthcertificate_url', 'rider_parental_consent_url'], 'string', 'max' => 100],
[['rider_no_tlpn'], 'string', 'max' => 15],
[['rider_ucinumber'], 'string', 'max' => 11]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'rider_id' => 'rider_id',
'cagories_category_id' => 'Category Name',
'user_id' => 'User Team',
'rider_firstname' => 'Rider Firstname',
'rider_lastname' => 'Rider Lastname',
'rider_nickname' => 'Rider Nickname',
'rider_email' => 'Rider Email',
'rider_no_tlpn' => 'Rider No Tlpn',
'rider_ucinumber' => 'Rider Ucinumber',
'countries_id' => 'Country Name',
'rider_province' => 'Rider Province',
'rider_city' => 'Rider City',
'rider_sponsor' => 'Rider Sponsor',
'rider_dateofbirth' => 'Rider Dateofbirth',
'rider_gender' => 'Rider Gender',
'rider_birthcertificate_url' => 'Rider Birthcertificate Url',
'rider_parental_consent_url' => 'Rider Parental Consent Url',
'rider_status' => 'Rider Status',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getRegistrations()
{
return $this->hasMany(Registrations::className(), ['riders_rider_id' => 'rider_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCagoriesCategory()
{
return $this->hasOne(Categories::className(), ['category_id' => 'cagories_category_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']) -> from(user::tableName() . 'ud');
}
/**
* #return \yii\db\ActiveQuery
*/
public function getUserDesc()
{
return $this->hasOne(UserDesc::className(), ['desc_id' => 'user_id']) -> from(['ud' => userDesc::tableName()]);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCountries()
{
return $this->hasOne(Countries::className(), ['id' => 'countries_id']);
}
}
This my Controller actionIndex:
$searchModel = new RidersSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$totalCount = Yii::$app->db->createCommand('SELECT COUNT(*) FROM riders WHERE user_id = :user_id',
[':user_id' => Yii::$app->user->identity->id])->queryScalar();
$dataProvider = new SqlDataProvider([
'sql' => 'SELECT * FROM riders WHERE user_id = :user_id',
'params' => [':user_id' => Yii::$app->user->identity->id],
'totalCount' => $totalCount,
'key' => 'rider_id',
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'attributes' => [
'cagories_category_id',
'rider_id',
'rider_firstname',
'rider_email:email',
'rider_no_tlpn',
]
]
]);
$models = $dataProvider->getModels();
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
This is my view index:
<?= GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'label' => 'Category Name',
'attribute'=>'cagories_category_id',
'value' => 'cagoriesCategory.category_name', <---Can't work again
],
[
'label' => 'BIB',
'attribute'=>'rider_id',
],
'rider_firstname',
'rider_email:email',
'rider_no_tlpn',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
Before I use sqldataprovider, it can call from model function have relation, after use sqldataprovider can't work. How to get relation table value???
then before use it, i can to merge rider_firstname and rider_lastname with return $model->rider_firstname . " " . rider_lastname; after use sqldataprovider can't work too??
SqlDataProvider returns data as an array so You can't able to access related object with $dataProvider->models()
either you have to use ActiveDataProvider or change your Sql of SqlDataProvider with join condition
sql='sql' => 'SELECT * FROM riders inner join '. Categories::tableName() .' as c on c.category_id=riders.cagories_category_id WHERE user_id = :user_id'