creation time is invalid when update in yii2 - yii2

when I want to update form in yii2
It tells me this error
creation time is invalid -- update time is invalid
What do you think is it?
public function beforeSave($insert)
{
$date = new \DateTime();
$date->setTimestamp(time());
$date->setTimezone(new \DateTimezone('Istanbul'));
$this->update_time = $date->format('Y-m-d H:i:s');
if($this->isNewRecord)
$this->creation_time = $date->format('Y-m-d H:i:s');
return parent::beforeSave($insert);
}
My problem has been resolved
change date to safe in rules
[['creation_time', 'update_time'], 'safe'],

Your code is correct "Nader" but some time assigning the value not work so just remove the value or use this
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'create_time',
'updatedAtAttribute' => 'update_time',
//'value' => new Expression('NOW()'),
],
];
}
Just comment the value,
it will work.
For more detail https://www.yiiframework.com/doc/api/2.0/yii-behaviors-timestampbehavior

Just could just use the available TimestampBehavior behavior
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;
use yii\db\ActiveRecord;
class Mymodel extends ActiveRecord{
public function behaviors() {
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'creation_time',
'updatedAtAttribute' => 'update_time',
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time',
ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
],
'value' => new Expression('NOW()')
]
];
}
}
Remove any validation rules from your model you may have for this two attributes
creation_time and update_time

Related

Insert or update in laravel?

What would be the best way to set this query? i can't seem to find any documentation on an actual insert or update that works, I'm hoping to do it via the Eloquent model but can't seem to get it working
any help would be appreciated.
DB::table('questions')->insert([
'marital_status' => $request->marital_status,
'job_title' => $request->job_Title,
'industry' => $request->industry,
'occupation' => $request->occupation,
'paye' => $request->paye,
'self_employed' => $request->self_employed,
'child_benefit' => $request->child_benefit,
'work_home' => $request->work_home,
'own_transport' => $request->own_transport,
'company_vehicle' => $request->company_vehicle,
'annual_income' => $request->annual_income,
'pay_memberships' => $request->pay_memberships,
'income_benefits' => $request->income_benefits,
'printer' => $request->printer,
'contact' => $request->contact,
'share' => $request->share,
'terms' => $request->terms,
'user_id' => $user
]);
here is my Model for Questions
<?php
namespace App;
class Questions extends Model
{
protected $fillable = [
'marital_status',
'job_title',
'industry',
'occupation',
'paye',
'self_employed',
'child_benefit',
'work_home',
'own_transport',
'company_vehicle',
'annual_income',
'pay_memberships',
'income_benefits',
'printer',
'contact',
'share',
'terms',
'user_id'
];
public function users(){
return $this->hasOne('App\User');
}
}
Use Eloquent with mass assignment:
Question::updateOrCreate($request->all()->put('user_id', $user));
Or:
$question = Question::firstOrNew('some_id', $someId);
$question->fill($request->all()->put('user_id', $user))->save();
Don't forget to fill $fillable array with all properties you want to persist:
class Question extends Model
{
protected $fillable = [
'marital_status',
'job_title',
'industry',
'occupation',
'paye',
'self_employed',
'child_benefit',
'work_home',
'own_transport',
'company_vehicle',
'annual_income',
'pay_memberships',
'income_benefits',
'printer',
'contact',
'share',
'terms',
'user_id'
]
Update
If put() method doesn't work for some reason, try this:
$request->merge(['user_id' => $user]);
And then just use $request->all()
Or:
$requestData = $request->all();
$requestData['user_id'] = $user;
And then use $requestData

Capcha always show incorrect

I have used capcha in one of my forms. It always give verification code incorrect error.
Below is my code:
SchoolsController.php
public function actions() {
return [
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fontFile' => '#yii/captcha/SpicyRice.ttf',
'padding' => '0',
]
];
}
Model:
['verifyCode', 'captcha', 'captchaAction' => 'schools/captcha'],
View:
echo $form->field($modelSchoolRequestEarlyAccess, 'verifyCode')->widget(Captcha::className(), [
'options' => [
'placeholder' => 'Enter characters in the image',
'autocomplete' => 'off',
'maxlength' => 20
],
'captchaAction' => 'schools/captcha',
'template' => "<div class='field'><span><strong>*</strong>".Yii::t('frontend/quicksignup','VerifyCodeLabel').":</span></span>\n<div>{image}{input}<i class='refresh-code-icn' id='get-new-code'></i></div></div>"
])->label(false);
I have specified the captcha action as schools/captcha in model as well as view. But it always show verification incorrect.
What am I doing wrong??
You wrote SchoolController.php and your route is to schools. So you probably need to adjust your route to school/captcha
Did you add the rules?
public function rules()
{
$rules = parent::rules();
$rules[] = ['captcha', 'required'];
$rules[] = ['captcha', 'captcha'];
return $rules;
}

How to connect 3 tables in yii2 and display in Gridview then make sorting work correctly

I have used the gii tool to create crud application. I have 3 tables the tbl_targetcities, lib_cities, and lib_provinces. I was able to connect lib_cities to tbl_targetciteis but not the lib_provinces. And also the sorting of city / Municipality does not work. It seems that it sorts according ti the ID.
tbl_target_cities
lib_cities
lib_provinces
sample View
So far here is my relation in the model.
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code']);
}
in my view file...
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute'=>'city_code',
'value'=>'cityName.city_name'
],
[
'attribute'=>'prov code',
'value'=>'cityName.city_name'
],
'kc_classification',
'cluster',
'grouping',
'priority',
'launch_year',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
How to display the prov_name from lib_provinces???
EDIT to answer user2839376 question in the comment box
IN THE SEARCH MODEL CLASS
$query = TblSpBub::find();
$query->joinWith('brgyCode')->joinWith(['cityCode'])->joinWith(['cityCode.provCode']);
$covered= LibAreas::find()->where(['user_id'=>yii::$app->user->identity->id])->all();
$query->all();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort'=> ['defaultOrder' => ['id'=>SORT_DESC]],
]);
$dataProvider->sort->attributes['city'] = [
'asc' => ['lib_Cities.city_name' => SORT_ASC],
'desc' => ['lib_Cities.city_name' => SORT_DESC],
];
$dataProvider->sort->attributes['province'] = [
'asc' => ['lib_provinces.prov_name' => SORT_ASC],
'desc' => ['lib_provinces.prov_name' => SORT_DESC],
];
In LibCities model add new relation:
public function getProvince()
{
return $this->hasOne(LibProvince::className(),['prov_code'=>'prov_code']);
}
And change getCityName relation. You should add with() for relation:
public function getCityName()
{
return $this->hasOne(LibCities::className(),['city_code'=>'city_code'])->with(['province']);
}
And in view correct your columnto this:
[
'attribute'=>'prov code',
'value'=>'cityName.province.prov_name'
],
You have to use the function relations() in models.
In tbl_target_cities model:
public function relations()
{
return array(
'city' => array(self::HAS_ONE, 'LibCities', 'city_code'),
);
}
In LibCities model :
public function relations()
{
return array(
'province' => array(self::HAS_ONE, 'LibProvinces', 'prov_code'),
'targets' => array(self::HAS_MANY, 'TargetCity', 'city_code',
);
}
This will allowed you to jump throw the LibCities model,
now you can simply acces to prov name like this :
$model->city->province->prov name;
Note : You need to have the 3 models defined.
EDIT
array(
'name' => 'province name',
'value' => $data->city->province->prov_name;
),
Done it, Heres how.
in addition to the above code (original post)
// in Model I added an additional function
public function getTaskowner()
{
return $this->hasOne(Tasks::className(), ['id' => 'task_id'])
->with(
['location','taskowner']
);
}
and in view i did this
....
'columns' => [
....
[
'class' => 'kartik\grid\DataColumn',
'value'=> 'tasks.location.taskowner.name',
.....
],
.....
and it worked
key points. used an array with the 'with->(..)' to include both then in the view added 'tasks.location.taskowner.name', to join them all

Setting default values on create and update in yii

I am trying to update some fields in yii 1.1 using the following rules, but it is not working.
public function rules()
{
return [
['CreatedOn','default','value'=>time(),'isEmpty'=>true,'on'=>'insert'],
['CreatedBy','default','value'=>\Yii::$app->user->identity->id,'isEmpty'=>true,'on'=>'insert'],
['ModifiedOn','default','value'=>time(),'isEmpty'=>true,'on'=>'update'],
['ModifiedBy','default','value'=>\Yii::$app->user->identity->id,'isEmpty'=>true,'on'=>'update'],
];
}
I am looking to update CreatedBy and CreatedOn when inserting, and ModifiedBy and ModifiedOn when updating.
From soju's excellent answer, with Yii2:
By default, a model supports only a single scenario named default
You should therefore set the scenario manually in your controller i.e:
$model->scenario = 'insert';
You could also use when instead of on i.e:
['CreatedOn', 'default', 'value'=>time(), 'isEmpty'=>true, 'when'=>
function($model) { return $model->isNewRecord; }
],
['ModifiedOn', 'default', 'value'=>time(), 'isEmpty'=>true, 'when'=>
function($model) { return !$model->isNewRecord; }
],
An alternative to setting them in rules() would be to use beforeSave() to set them:
public function beforeSave($insert) {
if ($insert) {
$this->CreatedBy = \Yii::$app->user->identity->id;
$this->CreatedOn = time();
} else {
$this->ModifiedBy = \Yii::$app->user->identity->id;
$this->ModifiedOn = time();
}
return parent::beforeSave($insert);
}
This is the correct way to do it:
Behaviors:
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'created_on',
ActiveRecord::EVENT_BEFORE_UPDATE => 'modified_on',
ActiveRecord::EVENT_BEFORE_DELETE => 'deleted_at',
],
'value' => function () {
return date('Y-m-d H:i:s');
}
],
[
'class' => BlameableBehavior::className(),
'createdByAttribute' => 'created_by_id',
'updatedByAttribute' => 'updated_by_id',
],
];
}
If you need just a simple rule for default value, this is enough:
public function rules()
{
return [
['CreatedOn','default','value'=>time()],
['ModifiedOn','default','value'=>time(),'isEmpty'=>true],
...
]
}
The 'isEmpty'=>true option override the default isEmpty() function and returns true (it is always seen as empty) dues it is always populated with time()
For Yii2 version 2.0.8 from April 2016 I had an error with 'isEmpty'=>true because according to documentation it expects a function so you must to do like this:'isEmpty' => function ($value) {return true;}.
When you use this solution you get a value for ModifiedBy even on create and I believe that was not an intention. It is possible to write isEmpty to return true in case of an update but I simply used 'when' because it is much more readable for me. So, my solution for rules in a model was :
['CreatedBy', 'default', 'value' => Yii::$app->user->id],
['ModifiedBy', 'default', 'value' => Yii::$app->user->id,
'when' => function ($model) { return !$model->isNewRecord;}],
As a side note for this question is that for timestamps you should rely on database to fill them, CreatedOn with default value and a before update trigger for ModifiedOn.

Yii2 validation rule specific to a scenarios

I have the following rules and scenarios
public function rules(){
return [
[['name','email','password'],'required'],
['email','myvalidation'],
['email','email'],
[['name', 'email', 'password'], 'required', 'on' => 'register'],
];
}
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['login'] = ['name','password','email'];//Scenario Values Only Accepted
return $scenarios;
}
I want the rule 'myvalidation' applied only to the login scenario and not at all in other cases.How this can be achieved in Yii2 ?
Remember you can also use "except". In example:
public function rules()
{
return [
[['first_name', 'email', 'phone', 'password'], 'required', 'except' => 'changepassword'],
[['password'], 'required', 'on' => 'changepassword']
]}
Just specify on property in this validation rule:
['email', 'myvalidation', 'on' => 'login'],