I’m having trouble with Yii 2.0 doing a basic implementation of the advanced template. I’m just trying to get the user signup and login working. I started with the boilerplate from yii and made very little changes. I simply matched up the tbl_user columns to the attributes listed on the model. Then I figured that I had to rename the table to user, but that didn’t work and I couldn’t find anywhere where the table name was set to tbl_user, but apparently it’s looking for that name in the user model.
The next problem I had was that the password was not being encrypted when I registered a user. So I followed the process through the code:
site controller has a signup action:
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
$user = $model->signup();
if ($user) {
if (Yii::$app->getUser()->login($user)) {
return $this->goHome();
}
}
}
return $this->render('signup', [
'model' => $model,
]);
}
this calls the signupform model and sign up method:
public function signup()
{
if ($this->validate()) {
return User::create($this->attributes);
}
return null;
}
Which calls User::create on the user model:
public static function create($attributes)
{
/** @var User $user */
$user = new static();
$user->setAttributes($attributes);
$user->setPassword($attributes['password']);
$user->generateAuthKey();
if ($user->save()) {
return $user;
} else {
return null;
}
}
Which calls setPassword:
public function setPassword($password)
{
$this->password_hash = Security::generatePasswordHash($password);
}
So in all this, I see where it’s setting the password before saving, but not encrypting. So I wrote a simple method:
{
/** @var User $user */
$user = new static();
$user->setAttributes($attributes);
$user->setPassword($attributes['password']);
$user->hashPassword();
$user->generateAuthKey();
if ($user->save()) {
return $user;
} else {
return null;
}
}
This works, however, now I can't login the user, password does not match apparently. At this point I'm a little lost. Can anyone point me in the right direction? Is there a working example of the boilerplate 2.0 advanced? I would greatly appreciate any help, thanks.
Ok, so did a fresh install and retraced my steps. I did not need a new method. Just a few tweaks and got a working result possibly. Had to add a password rule to the user model. Had to change logout verb from post to get. So it works, I think, if I understand it correctly, and there is no guarantee that I do It looks like it saves a password and a hash_password into the db. The password itself is not encrypted and this is what really threw me. The password is a combination of the password and the hash_password. Is this correct? As far as I can tell, this is how it works. If this is intended, it seems like a really bad practice…
Any help is greatly appreciated, this is my first try with 2.0, thanks!
Thanks Orey, I really appreciate your help. I’m new to this so I am making very basic mistakes. For example, I followed the links you suggested and realized that I wasn’t using a migration to create the table and that there might be differences, so I dropped the table and did a migration and sure enough there were. So by creating the table manually, I had put in a password column which it does not need. It uses password_hash instead. This is also why the password rule was not required.
Once I ran the migration the docs suggest, everything worked perfectly.
The behaviours for timestamp are working as well. I noticed that the table created by migration used int(11) instead of DateTime, which is what I had when I created the table manually, for the format of the column. Do you know why they are using this format? Also, the value stored from a signup: 1393778790 for example, I don’t know what this represents. Any insight would be greatly appreciated. Thanks again.
I have no idea. Anyway, Yii does not force you to use this or that, it’s pretty flexible, you can use whatever you want (personally I use Postgres and ‘TIMESTAMP WITH TIME ZONE’ type)
For example see docs on autotimestamp behavior. You can modify not only the column names but also a value inserted.