I am working on yii2. I have created a dynamic form using wbraganca
/
yii2-dynamicform. Now I want to implement the view. In the given extension there is no procedure that has implemented a view. It just shows the action method of view. I have tried to implement but couldn't able to do it completely.
Controller Code
/**
* Finds the MdcTariffSlabs model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return MdcTariffSlabs|\yii\db\ActiveQuery
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModelSlabs($id)
{
if (($model = MdcTariffSlabs::find()->where(['t_id'=>$id])) !== null) {
return $model;
}
throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
public function actionView($id)
{
$model = $this->findModel($id);
$modelTarrifSlabs = $this->findModelSlabs($model->id);
return $this->render('view', [
'model' => $model,
'modelTarrifSlabs' => $modelTarrifSlabs,
]);
}
View
/* #var $this yii\web\View */
/* #var $model common\models\MdcTariff */
/* #var $modelTarrifSlabs \common\models\MdcTariffSlabs */
.
.
.
.
.
.
.
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
't_name',
'created_by',
'created_at',
],
]) ?>
<?= DetailView::widget([
'model' => $modelTarrifSlabs,
'attributes' => [
'id',
't_name',
'created_by',
'created_at',
],
]) ?>
After creating I am rendering my view and getting an error
Getting unknown property: yii\db\ActiveQuery::id
var_dump($modelTarrifSlabs);
exit();
The above code gives me
object(yii\db\ActiveQuery)#131 (33) { ["sql"]=> NULL ["on"]=> NULL ["joinWith"]=> NULL ["select"]=> NULL ["selectOption"]=> NULL ["distinct"]=> NULL ["from"]=> NULL ["groupBy"]=> NULL ["join"]=> NULL ["having"]=> NULL ["union"]=> NULL ["withQueries"]=> NULL ["params"]=> array(0) { } ["queryCacheDuration"]=> NULL ["queryCacheDependency"]=> NULL ["_events":"yii\base\Component":private]=> array(0) { } ["_eventWildcards":"yii\base\Component":private]=> array(0) { } ["_behaviors":"yii\base\Component":private]=> array(0) { } ["where"]=> array(1) { ["t_id"]=> int(1) } ["limit"]=> NULL ["offset"]=> NULL ["orderBy"]=> NULL ["indexBy"]=> NULL ["emulateExecution"]=> bool(false) ["modelClass"]=> string(28) "common\models\MdcTariffSlabs" ["with"]=> NULL ["asArray"]=> NULL ["multiple"]=> NULL ["primaryModel"]=> NULL ["link"]=> NULL ["via"]=> NULL ["inverseOf"]=> NULL ["viaMap":"yii\db\ActiveQuery":private]=> NULL }
I think your error is because you get an Active Query instead of Model. And that what the error says:
Getting unknown property: yii\db\ActiveQuery::id
Try this:
Change this:
protected function findModelSlabs($id)
{
if (($model = MdcTariffSlabs::find()->where(['t_id'=>$id])) !== null) { //<---- here i guess you have error
return $model;
}
throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
To this:
protected function findModelSlabs($id)
{
if (($model = MdcTariffSlabs::find()->where(['t_id'=>$id])->one()) !== null) {
return $model;
}
throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
Related
In my Kartik GridView viewfile, I am attempting to process a function for the detailRowCssClass property of an ExpandRowColumn. Regardless of setup, (such as applying an empty function or returning direct strings), the result is always the same and an object is returned.
'detailRowCssClass' => function($data){
if($data->status == 0)
{
return GridView::TYPE_INFO;
}
elseif($data->status == 1)
{
return GridView::TYPE_WARNING;
}
elseif($data->status == 2)
{
return GridView::TYPE_SUCCESS;
}
},
returns a class of [object Object]
Does anyone know a workaround, or what I am fundamentally missing in that this does not return a string? Thanks!
The problem is, that detailRowCssClass of the class kartik\grid\ExpandRowColumn is a simple string and not a closure. The appropriate parts from the source file vendor/kartik-v/yii2-grid/src/ExpandRowColumn.php:
class ExpandRowColumn extends DataColumn
{
...
/**
* #var string the CSS class for the detail content table row.
*/
public $detailRowCssClass;
...
/**
* #inheritdoc
* #throws InvalidConfigException
*/
public function init()
{
if (!isset($this->detailRowCssClass)) {
$this->detailRowCssClass = $this->grid->getCssClass(GridView::BS_TABLE_INFO);
}
...
$clientOptions = Json::encode(
[
'gridId' => $this->grid->options['id'],
'hiddenFromExport' => $this->hiddenFromExport,
'detailUrl' => empty($this->detailUrl) ? '' : $this->detailUrl,
'onDetailLoaded' => $onDetailLoaded,
'expandIcon' => $this->expandIcon,
'collapseIcon' => $this->collapseIcon,
'expandTitle' => $this->expandTitle,
'collapseTitle' => $this->collapseTitle,
'expandAllTitle' => $this->expandAllTitle,
'collapseAllTitle' => $this->collapseAllTitle,
'rowCssClass' => $this->detailRowCssClass,
'animationDuration' => $this->detailAnimationDuration,
'expandOneOnly' => $this->expandOneOnly,
'enableRowClick' => $this->enableRowClick,
'enableCache' => $this->enableCache,
'rowClickExcludedTags' => array_map('strtoupper', $this->rowClickExcludedTags),
'collapseAll' => false,
'expandAll' => false,
'extraData' => $this->extraData,
]
);
...
}
controller
After being saved, the ID is equal to the null in the batchInsert
$model= new Sale();
if($model->load(Yii::$app->request->post())) {
$model->status=1;
$model->price = str_replace(",","",$model->price);
//$id = $model->id
$model->save();
$id = $model->id;
if($model->pardakht == 1) {
for($i=0;$i<$model->count;$i++) {
$data[$i][0]=Yii::$app->request->post('number_check')[$i];
$data[$i][1]=Yii::$app->request->post('price_check')[$i];
$data[$i][2]=Yii::$app->request->post('date_check')[$i];
$data[$i][3]=Yii::$id;
$data[$i][4]=Yii::$model->customer_id;
}
Yii::$app->db->creatCommand()->batchInsert('sale_check', [
'number_check',
'price_check',
'date_check',
'user_id',
'customer_id'
], $data)->execute();
}
}
var_dump($id);
$id = null ????????????
Your model has an error, to find where the problem and what attributes has error,
Change this:
$model->save();
$id = $model->id;
to
if($model->save()) {
$id = $model->id;
/** other codes ****/
}else{
var_dump($model->errors);
/** or other usage of this array result **/
}
I want to validate my fine_amount against 2 input date. But it does not return any error. Without validating this method it saved data.
I also looked into
Yii2: how to use custom validation function for activeform? but for me no solution.
Below is my code
Controller method
$model = $this->findModel($id);
$model->payment_date=date('d-M-Y',strtotime($model->payment_date));
$model->payment_expected_date=date('d-M-Y',strtotime($model->payment_expected_date));
if ($model->load(Yii::$app->request->post())) {
$model->payment_date=date('Ymd',strtotime($model->payment_date));
$model->payment_expected_date=date('Ymd',strtotime($model->payment_expected_date));
if($model->validate()){
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
else{
$model->payment_date=date('d-M-Y',strtotime($model->payment_date));
$model->payment_expected_date=date('d-M-Y',strtotime($model->payment_expected_date));
return $this->render('update', [
'model' => $model,
]);
}
}
return $this->render('update', [
'model' => $model,
]);
My Rule
['fine_amount' , 'fine_required'] ,
Validation function
public function fine_required() {
$this->payment_date = date ( 'Ymd' , strtotime ( $this->payment_date ) );
$this->payment_expected_date = date ( 'Ymd' , strtotime ( $this->payment_expected_date ) );
if ( $this->payment_date > $this->payment_expected_date ) {
if ( $this->fine_amount <= 0 ) {
$this->addError ( 'fine_amount' , 'Fine Amount Must be add.' );
}
return false;
}
return true;
}
You need to use conditional validation for your case, use when and whenClient respectively see below add to your rules section and remove any other validations. This will handle frontend and backend both validations
[ 'fine_amount' , 'required' , 'when' => function($model) {
if ( $model->payment_date > $model->payment_expected_date ) {
if ( $model->fine_amount <= 0 ) {
return true;
}
}
return false;
} , 'whenClient' => 'function (attribute, value) {
var d1 = new Date($("#' . Html::getInputId($this, 'payment_date') . '").val());
var d2 = new Date($("#' . Html::getInputId($this, 'payment_expected_date'). '").val());
if(d1>d2){
if(value<=0){
return true;
}
}
return false;
}' , 'message' => 'Fine Amount Must be add.' ] ,
EDIT
Replaced strtolower ( \yii\helpers\StringHelper::basename ( get_class ( $this ) ) ) with Html::getInputId as it is more suitable for this case.
I'm using yii2-advanced. I've several table :
tb_user:(iduser(PK),username),
tb_profile:(id,iduser(FK)),
tb_status:(id,iduser(FK))
My question is how can i insert iduser(PK) from tb_user to iduser(FK) on tb_profile and tb_status after i push the signup button.
For a while i think i must to do some modification of bevahiours() function on User model and i found some error, or adding trigger syntax on the table ? (i think this is not a good ways).
Is there anyone who can help me, how to solve my problem ?
this is the User model before the modification :
<?php
namespace common\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
/**
* #inheritdoc
*/
public static function tableName()
{
return '{{%user}}';
}
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'created_at',
ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at',
],
'value' => function () {return date('Y-m-d h:m:s');},
],
];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
}
?>
The Controller :
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->render('signup', [
'model' => $model,
]);
}
I had similar situation in one of my project where i had 2 tables like user,user_image where user_id was foreign key to add the path.
For those kind of situation you can use either of following approach
1.Insert record in both table on click of signup button. You will have to write update action accordingly.
$user = new User();
$user->name = "John"
$user->email = "John#gmail.com"
//Add if any other fields in table
$user->save(); //save the record
$user_image = new UserImage();
$user_image->user_id = $user->id;
$user_image->image = "image path"
//Add any other images here
$user_image->save();//save the record
2.You can also call create action of UserImage and do the same. If you use this approach than you might also need to use any other unique column to find the id of that user and use it to insert new record,for example in my table email is unique column so i can write following code in UserImage and get the id
$user = User::findOne(['email' => 'john#gmail.com']);//this will return whole row
$user_image->user_id = $user->id;
$user_image->image = "image path"
//Add any other images here
$user_image->save();//save the record
And that way you can use the code as per it suits your need
Thank you
I created src/Model/Behavior/ModernTreeBehavior.php:
<?php
namespace Cake\ORM\Behavior;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Event\Event;
use Cake\ORM\Behavior;
use Cake\ORM\Entity;
use Cake\ORM\Query;
use InvalidArgumentException;
use RuntimeException;
class ModernTreeBehavior extends Behavior
{
/**
* Cached copy of the first column in a table's primary key.
*
* #var string
*/
protected $_primaryKey;
/**
* Default config
*
* These are merged with user-provided configuration when the behavior is used.
*
* #var array
*/
protected $_defaultConfig = [
'implementedFinders' => [
'children' => 'findChildren',
'treeList' => 'findTreeList'
],
'implementedMethods' => [
'childCount' => 'childCount',
'getLevel' => 'getLevel'
],
'parent' => 'parent_id',
'path' => 'path',
'scope' => null,
'level' => null
];
public function getLevel($entity)
{
$primaryKey = $this->_getPrimaryKey();
$id = $entity;
if ($entity instanceof EntityInterface) {
$id = $entity->get($primaryKey);
}
$config = $this->config();
$entity = $this->_table->find('all')
->select([$config['path']])
->where([$primaryKey => $id])
->first();
if ($entity === null) {
return false;
}
return substr_count($entity[$config['path']], '-') + 1;
}
/**
* Returns a single string value representing the primary key of the attached table
*
* #return string
*/
protected function _getPrimaryKey()
{
if (!$this->_primaryKey) {
$this->_primaryKey = (array)$this->_table->primaryKey();
$this->_primaryKey = $this->_primaryKey[0];
}
return $this->_primaryKey;
}
}
I used $this->addBehavior('ModernTree'); in CommentTables.php
and I got error Fatal error: Cannot redeclare class Cake\ORM\Behavior\ModernTreeBehavior in .../src/Model/Behavior/ModernTreeBehavior.php on line 0
But if I paste /src/Model/Behavior/ModernTreeBehavior.php into built-in file TreeBehavior.php and load TreeBehavior.php, everything so goods.
Can you tell me the reason?
The namespace declaration of your class is wrong, it should be:
namespace App\Model\Behavior;