Yii2 | GridView table, communication between models does not work - php

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.

Related

Codeigniter 4 - Form Validation

I'm using the validation form of CodeIgniter 4, I already check if the post is coming, but I'm receiving FALSE every time, just take a look in my code.
function login(){
helper(['form', 'url']);
$validation = \Config\Services::validation();
$validation->setRules([
'email' => ['label' => 'E-mail', 'rules' => 'required'],
'password' => ['label' => 'Senha', 'rules' => 'required|min_length[6]']
]);
var_dump($this->validate($validation) ? true : false);exit;
}
I tried too,
$rules = [
'email' => ['label' => 'E-mail', 'rules' => 'required'],
'password' => ['label' => 'Senha', 'rules' => 'required|min_length[6]']
];
var_dump($this->validate($rules) ? true : false);exit;
look at my codes
<?php
namespace Modules\Common\Controllers;
use Modules\Common\Config\Services;
use Modules\Common\Entities\AdvertisementEntity;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Shared\Controllers\ApiController;
class Advertisement extends ApiController
{
/**
* index function
* #method : GET
*/
public function index()
{
$advertisementEntity = new AdvertisementEntity();
$this->urlQueryParam->dataMap($advertisementEntity->getDataMap());
$advertisementService = Services::advertisementService();
$findAllData = $advertisementService->index($this->urlQueryParam);
return $this->respond([
'data' => $findAllData['data'],
'pager' => $findAllData['pager']
], ResponseInterface::HTTP_OK, lang('Shared.api.receive'));
}
/**
* show function
* #method : GET with params ID
*/
public function show($id = null)
{
$advertisementService = Services::advertisementService();
$findOneData = $advertisementService->show($id);
return $this->respond([
'data' => $findOneData['data'],
'pager' => $findOneData['pager']
], ResponseInterface::HTTP_OK, lang('Shared.api.receive'));
}
/**
* create function
* #method : POST
*/
public function create()
{
$rules = [
'name' => 'required|min_length[3]|max_length[255]',
'link' => 'required',
];
if (!$this->validate($rules)) {
return $this->respond([
'error' => $this->validator->getErrors(),
], ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Shared.api.validation'));
};
$advertisementEntity = new AdvertisementEntity((array)$this->request->getVar());
$advertisementEntity->enableStatus()->createdAt();
$advertisementService = Services::advertisementService();
$advertisementService->create($advertisementEntity);
return $this->respond([
'insertId' => $advertisementService->getInsertID()
], ResponseInterface::HTTP_CREATED, lang('Shared.api.save'));
}
/**
* update function
* #method : PUT or PATCH
*/
public function update($id = null)
{
if ($this->request) {
//get request from Vue Js
$json = $this->request->getJSON();
if (!isset($id)) {
$id = $json->id;
}
$rules = [
'name' => 'required|min_length[3]|max_length[255]',
'link' => 'required',
];
if (!$this->validate($rules)) {
return $this->respond([
'error' => $this->validator->getErrors(),
], ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Shared.api.validation'));
}
$advertisementEntity = new AdvertisementEntity((array)$this->request->getVar());
$advertisementEntity->updatedAt();
$advertisementService = Services::advertisementService();
$advertisementService->update($id, $advertisementEntity);
}
return $this->respond([
], ResponseInterface::HTTP_OK, lang('Shared.api.update'));
}
/**
* edit function
* #method : DELETE with params ID
*/
public function delete($id = null)
{
$advertisementService = Services::advertisementService();
$advertisementService->delete($id);
return $this->respond([
], ResponseInterface::HTTP_OK, lang('Shared.api.remove'));
}
}

Yii2 Grid view syntax to access data from related model

for example I can retrieve the data in the view with this command:
<?=$model->instructor->manager->location['location_title']?>
I have a relation defined in Instructor model like:
/**
* #return mixed
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
/**
* #return mixed
*/
public function getManager()
{
return $this->hasOne(Manager::className(), ['user_id' => 'manager_id']);
}
and in Manager Model relations are defined like this:
/**
* #return mixed
*/
public function getLocation()
{
return $this->hasOne(Location::className(), ['id' => 'location_id']);
}
/**
* #return mixed
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
Now How I can retrieve the same data in grid-view as also add filter for the same.
Thanks.
update: Gridview Code
echo GridView::widget(
[
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
'first_name',
'last_name',
// 'username',
// 'auth_key',
// 'password_hash',
// 'password_reset_token',
'email:email',
// 'phone',
//'user_role',
['attribute' => 'created_at', 'label' => 'Last Login', 'value' => function ($data) {
return $data->getLast($data);
},
'contentOptions' => ['style' => 'width:100px']
],
['attribute' => 'created_at', 'label' => 'Create Date', 'contentOptions' => ['style' => 'width:100px'], 'value' => function ($data) {return date('M d, Y', $data->created_at);}
],
// 'updated_at',
['attribute' => 'status', 'value' => function ($data) {
return $data->getStatus($data);
},
'filter' => ['10' => 'Active', '0' => 'Deactive'],
'contentOptions' => function ($data) {
$clr = $data->status == 10 ? 'green' : 'red';
return ['style' => 'width:80px;font-weight:bold;color:' . $clr];
}
]
]
]
);
Update-1
public function actionInstructor()
{
$cond = "user_role='instructor' ";
$searchModel = new UserSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $cond);
return $this->render(
'instructor', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider
]
);
}
update-2
public function getInstructor()
{
return $this->hasOne(Instructor::className(), ['user_id' => 'id']);
}
You can specify relations either as a string of relation names concatenated with . like below. Make sure you have the relations defined in the respective models the below is for the $dataProvider from the UserSearch model and your User Model should have the relation getInstructor() defined
[
'intructor.manager.location.location_title'
]
or
[
'label' => 'Manager Location',
'value' => function($model){
return $model->instructor->manager->location->location_title;
}
]
if I have the $dataProvider for the UserSearch model below should be the gridview code.
<?=GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
//'id',
'first_name',
'last_name',
[
'label'=>'Manager Location'
'attribute'=>'manager_id'.
'value'=>function($model){
return $model->instructor->manager->location->location_title;
}
]
// 'username',
// 'auth_key',
// 'password_hash',
// 'password_reset_token',
'email:email',
// 'phone',
//'user_role',
['attribute' => 'created_at', 'label' => 'Last Login', 'value' => function ($data) {
return $data->getLast($data);
},
'contentOptions' => ['style' => 'width:100px'],
],
['attribute' => 'created_at', 'label' => 'Create Date', 'contentOptions' => ['style' => 'width:100px'], 'value' => function ($data) {return date('M d, Y', $data->created_at);}],
// 'updated_at',
['attribute' => 'status', 'value' => function ($data) {
return $data->getStatus($data);
},
'filter' => ['10' => 'Active', '0' => 'Deactive'],
'contentOptions' => function ($data) {
$clr = $data->status == 10 ? 'green' : 'red';
return ['style' => 'width:80px;font-weight:bold;color:' . $clr];
},
],

YII 2 relational data from third table

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.

Yii2 ActiveDataProvider sort using count in relational

Yii2 ActiveDataProvider sort using count in relational ?
I've 3 tables, bellow :
And I displaying data from table inventory_device_type, here is the code :
Controller :
<?php
namespace app\controllers\inventory;
use Yii;
use yii\base\Action;
use app\models\tables\InventoryDeviceType;
class DeviceInventory extends Action
{
public function run()
{
$model = new InventoryDeviceType();
$dataProvider = $model->search(Yii::$app->request->post());
return $this->controller->render('device-inventory',[
'dataProvider' => $dataProvider,
]);
}
}
Model :
<?php
namespace app\models\tables;
use yii\db\ActiveRecord;
use yii\data\ActiveDataProvider;
use yii\web\NotFoundHttpException;
class InventoryDeviceType extends ActiveRecord
{
public static function tableName()
{
return 'inventory_device_type';
}
public function rules()
{
return [
[['name','id_device_vendor'],'required'],
['name','unique']
];
}
public function attributeLabels()
{
return [
'id_device_vendor' => 'Device Vendor',
];
}
/** queries **/
public function findData($id)
{
if(($data = self::findOne($id)) == null){
throw new NotFoundHttpException;
}else{
return $data;
}
}
public function getNormal()
{
return $this->getList()->where(['inventory_device_list.device_condition' => 'normal'])->count();
}
public function getBroken()
{
return $this->getList()->where(['inventory_device_list.device_condition' => 'broken'])->count();
}
public function getSold()
{
return $this->getList()->where(['inventory_device_list.device_condition' => 'sold'])->count();
}
public function getTotal()
{
return $this->getList()->where(['!=','inventory_device_list.device_condition',''])->count();
}
public static function getVendorList($sort=[])
{
return InventoryDeviceVendor::find()->orderBy($sort)->all();
}
public function search($params, $spesific=[],$sort=[])
{
$query = self::find();
$query->where($spesific);
$query->joinWith(['list']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['defaultOrder' => $sort]
]);
$dataProvider->sort->attributes['vendor_name'] = [
'asc' => ['inventory_device_vendor.name' => SORT_ASC],
'desc' => ['inventory_device_vendor.name' => SORT_DESC],
];
/** sort on page device-inventory **/
$dataProvider->sort->attributes['device_vendor'] = [
'asc' => ['inventory_device_vendor.name' => SORT_ASC],
'desc' => ['inventory_device_vendor.name' => SORT_DESC],
];
/** sort on page device-inventory end **/
return $dataProvider;
}
/** queries end **/
/** relation **/
public function getListLeft()
{
return InventoryDeviceList::find();
}
public function getList()
{
return $this->hasMany(InventoryDeviceList::className(),['id_device_type' => 'id']);
}
public function getVendorLeft()
{
return InventoryDeviceVendor::find();
}
public function getVendor()
{
return $this->hasOne(InventoryDeviceVendor::className(),['id' => 'id_device_vendor']);
}
/** relation end **/
}
and here is the view :
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'layout' => '<div class="table-responsive">{items}</div> {summary} {pager}',
'columns' => [
[
'class' => 'yii\grid\SerialColumn',
'headerOptions' => ['width' => 50]
],
'name',
[
'attribute' => 'device_vendor',
'class' => 'yii\grid\DataColumn',
'value' => function($data){
return $data->vendor->name;
}
],
[
'attribute' => 'normal',
'class' => 'yii\grid\DataColumn',
'format' => 'html',
'value' => function($data){
return Html::a($data->getNormal(),'#',['class' => 'label label-success']);
},
],
[
'attribute' => 'sold',
'class' => 'yii\grid\DataColumn',
'format' => 'html',
'value' => function($data){
return Html::a($data->getSold(),'#',['class' => 'label label-warning']);
},
],
[
'attribute' => 'broken',
'class' => 'yii\grid\DataColumn',
'format' => 'html',
'value' => function($data){
return Html::a($data->getBroken(),'#',['class' => 'label label-danger']);
},
],
[
'attribute' => 'Total',
'class' => 'yii\grid\DataColumn',
'format' => 'html',
'value' => function($data){
return Html::a($data->getTotal(),'#',['class' => 'label label-primary']);
},
],
],
]);
?>
and how to sort it, like normal, broken, and, sold ?
here is : the result view :
the header normal, sold, broke and all not sortable, i can sort by relation if not using count like this code (like Device Vendor):
$dataProvider->sort->attributes['device_vendor'] = [
'asc' => ['inventory_device_vendor.name' => SORT_ASC],
'desc' => ['inventory_device_vendor.name' => SORT_DESC],
];

YII2 SqlDataProvider doesn't work relation table value

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'

Categories