I've installed Yii2 advanced app, I customized the signup according to my user database. After signing up I tried to log in and it says "Incorrect username or password", my password is qwerty also I've checked it many times and it still does not work.
The signup model
class SignupForm extends Model
{
public $username;
public $email;
public $password;
public $first_name;
public $middle_name;
public $last_name;
public $contact;
public $birth_date;
public $type;
public $external_type;
public $status;
public $region_id;
public $barangay_id;
public $province_id;
public $city_municipal_id;
/**
* {#inheritdoc}
*/
public function rules()
{
return [
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
['first_name', 'required'],
['first_name', 'string', 'max' => 45],
['middle_name', 'string', 'max' => 45],
['last_name', 'required'],
['last_name', 'string', 'max' => 45],
['contact', 'required'],
['contact', 'string', 'max' => 11],
['birth_date', 'required'],
['type', 'required'],
['type', 'string', 'max' => 45],
['external_type', 'string', 'max' => 45],
['status', 'string', 'max' => 45],
['region_id', 'required'],
['barangay_id', 'required'],
['province_id', 'required'],
['city_municipal_id', 'required'],
];
}
/**
* Signs user up.
*
* #return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
$user->first_name = $this->first_name;
$user->middle_name = $this->middle_name;
$user->last_name = $this->last_name;
$user->contact = $this->contact;
$user->birth_date = $this->birth_date;
$user->type = $this->type;
$user->external_type = $this->external_type;
$user->status = $this->status;
$user->region_id = $this->region_id;
$user->barangay_id = $this->barangay_id;
$user->province_id = $this->province_id;
$user->city_municipal_id = $this->city_municipal_id;
return $user->save() ? $user : null;
}
}
Where did I get wrong here? It is confusing I think that there's no wrong in my code because I followed the proper installation setup of Yii2 Advanced App.
Login Model
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
}
return false;
}
check your user table in phpmyadmin, look at the status column, if this value not equal 10, you can change with 10.
Although you have'nt added the action for the registration or signup, but the point where you are calling the $model->signup() function from the model you must check it inside the if statement and then add a call to \Yii::$app->user->login($userModel); inside, it will log you in after signup.
Your signup() function returns the user model object after inserting the user in the table.
See below code sample
if(($userModel=$model->signUp())!==null){
\Yii::$app->user->login($userModel);
}
Hope it helps you out
Have you tried setting your user model class to implement the identity interface?
First declare your class like so
class MyUser extends ActiveRecord implements IdentityInterface
now somewhere in your class you need to implement these methods
public static function findIdentity($id)
{
return self::findOne(['id'=>$id]);
}
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException("Validation method not supported as of yet.");
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->auth_key;
}
public function validateAuthKey($authKey)
{
return $this->auth_key === $authKey;
}
next go to the components section of you /config/web.php and search for the 'user' component
'user' => [
'identityClass' => 'app\models\MyUser', //<---Your model class
'enableAutoLogin' => true,
],
I think with that your good to go. Let me know if this doesn't work.
Related
I want to change what is shown in my yii2 app's history view, so that I don't show a person's ID but his first and last name.
This is a part of my data grid
[
'attribute' => 'oldPerson.Id',
'label' => Yii::t('app', 'Previously In Charge'),
'value' => function($model){
return $model->person->FirstName . ' ' . $model->person->LastName; }
],
but this isn't good since my $model is a history object, which contains a person's ID. I somehow need to obtain the entire person object based on that ID, but I don't know how.
This is my Person model:
namespace app\models;
use Yii;
use \app\models\base\Person as BasePerson;
/**
* This is the model class for table "person".
*/
class Person extends BasePerson
{
public $created_at;
public $created_by;
public $updated_at;
public $updated_by;
public $id;
/**
* #inheritdoc
*/
public function rules()
{
return array_replace_recursive(parent::rules(),
[
[['FirstName', 'LastName', 'Title', 'CitizenNumber', 'Employment', 'Contact'], 'required'],
[['FirstName'], 'string', 'max' => 20],
[['LastName'], 'string', 'max' => 40],
[['Title'], 'string', 'max' => 50],
[['CitizenNumber'], 'string', 'max' => 13],
[['Employment', 'Contact'], 'string', 'max' => 100],
[['CitizenNumber'], 'unique']
]);
}
}
Normally you can get the model based on id this way
public function findModel($id)
{
if (($model = Person ::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
$model contain the Person info related to $id
its also working fine
$model=Modelname::findOne($id);
I can add user successfully, For Password hashing I am using md5() But when I update user it is giving an error.
Here are the model rules:
public function rules()
{
return [
[['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status'], 'required'],
['email','email'],
[['confirm'], 'compare', 'compareAttribute' => 'password','on'=>'create'],
[['firstname', 'lastname', 'username', 'email', 'password', 'confirm', ], 'string', 'max' => 255],
];
}
In the form i.e. View, I am using following code:
<div class="form-group">
<?php
if($case == 'create') { //this condition called when create user
echo $form->field($model, 'password')->passwordInput([
'maxlength' => true,
'placeholder' => 'Enter the Password',
]);
}
else { // during update
echo $form->field($model, 'password')->passwordInput([
'maxlength' => true,
'placeholder' => 'Enter the Password',
'value' => '',
]);
}
?>
</div>
<div class="form-group">
<?= $form->field($model, 'confirm')->passwordInput([
'maxlength' => true,
'placeholder' => 'Confirm Password',
]) ?>
</div>
and in controller I am using following code:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$case = "update";
if ($model->load(Yii::$app->request->post())) {
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
else {
return $this->render('update', [
'model' => $model,
'all_users_array' => $all_users_array,
'all_groups_array' => $all_groups_array,
'case' => $case,
]);
}
}
I am getting the error:
Undefined offset: 1 Failed to prepare SQL: UPDATE xbox_user SET
password=:qp0, role=:qp1, modified=:qp2, status=:qp3 WHERE
id=:qp4
Can anyone please let me what code should be modified there?
Thank you!
It is better to use scenarios in your case and use rules() too for other requirements, In Users.php model file write the following code:
public function scenarios(){
$scenarios = parent::scenarios();
$scenarios['create'] = ['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status', 'password','confirm'];
$scenarios['update'] = ['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status'];
return $scenarios;
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status', 'password','confirm'], 'required'],
['email', 'filter', 'filter' => 'trim'],
['email', 'unique' ],
['email', 'unique' ,'targetAttribute' => 'email'],
['email', 'required'],
['email', 'email'],
['email', 'unique', 'targetClass' => '\common\models\Users', 'message' => 'This email address has already been taken.'],
['confirm', 'compare', 'compareAttribute'=>'password', 'message'=>"Passwords does not match." ],
[['firstname', 'lastname', 'username', 'email', 'password', 'confirm', ], 'string', 'max' => 255],
];
}
In your views file use the following code:
<div class="form-group">
<?php
if($case == 'create'){
echo $form->field($model, 'password')->passwordInput(['maxlength' => true,'placeholder'=>'Enter the Password']);
}
else{
echo $form->field($model, 'password')->passwordInput(['maxlength' => true,'placeholder'=>'Enter the Password']);
}
?>
</div>
<div class="form-group">
<?= $form->field($model, 'confirm')->passwordInput(['maxlength' =>true,'placeholder'=>'Confirm Password']) ?>
</div>
and in your controller file, UsersController.php use the following code:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->scenario = 'update'; // calling scenario of update
if ($model->load(Yii::$app->request->post())) {
$req_array = yii::$app->request->post();
$role = $req_array['Users']['role'][0];
$model->role = $role;
if($req_array['Users']['password'] !== $req_array['Users']['confirm'])
{
$model->addError('confirm','Password and Confirm should be same.');
$model->password = $req_array['Users']['password'];
$model->confirm = $req_array['Users']['confirm'];
return $this->render('update', [
'model' => $model,
'all_users_array'=>$all_users_array,
'all_groups_array'=>$all_groups_array,
'case'=>$case,
]);
}
elseif( ($req_array['Users']['password'] == $req_array['Users']['confirm']) && (!empty($req_array['Users']['password'])))
{
$model->password = MD5($req_array['Users']['password']);
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
else
{
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
} else {
$model->password = '';
return $this->render('update', [
'model' => $model,
'all_users_array'=>$all_users_array,
'all_groups_array'=>$all_groups_array,
'case'=>$case,
]);
}
}
Using this code, you will not get error of required password in update, In case if you fill the password then process of confirm password and required will be run.
Hope this helps for you.
User Model
public function rules()
{
return [
[['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status'], 'required'],
['email','email'],
[['password', 'confirm'], 'required', 'on' => 'create'],
['confirm', 'compare', 'compareAttribute' => 'password', 'message'=>"Passwords does not match." ],
[['firstname', 'lastname', 'username', 'email', 'password', 'confirm', ], 'string', 'max' => 255],
];
}
Update Action
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->passowrd = '';
$model->confirm = '';
if ($model->load(Yii::$app->request->post())) {
$model->role = $model->role[0];
if (empty($model->password) || empty($model->confirm)) {
$model->password = $model->getOldAttribute('password');
$model->confirm = $model->getOldAttribute('confirm');
}
if ($model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
} else {
return $this->render('update', [
'model' => $model,
'all_users_array'=>$all_users_array,
'all_groups_array'=>$all_groups_array,
]);
}
}
Form
<div class="form-group">
<?= $form->field($model, 'password')->passwordInput(['maxlength' => true,'placeholder'=>'Enter the Password']) ?>
</div>
<div class="form-group">
<?= $form->field($model, 'confirm')->passwordInput(['maxlength' => true,'placeholder'=>'Confirm Password']) ?>
</div>
First try this one
[['confirm'], 'compare', 'compareAttribute' => 'password','on'=>'create']
if not work then please follow the following steps create your scenario for updation and don't compare password
Did you try scenarios.. i will give a simple example for user registration and user login i hope it will help you
<?php
class User extends Model
{
public $name;
public $email;
public $password;
public function rules(){
return [
[['name','email','password'],'required'],
['email','email'],
[['name', 'email', 'password'], 'required', 'on' => 'register'],
];
}
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['login'] = ['name','password'];//Scenario Values Only Accepted
return $scenarios;
}
}
?>
Apply Scenario For Model
See the below code, We added two ways of setting the scenario of a model. By default, scenario will support the model rules.
<?php
class UserController extends Controller
{
// APPLY SCENARIOS
// scenario is set as a property
public function actionLogin(){
$model = new User;
$model->scenario = 'login';
}
// scenario is set through configuration
public function actionRegister(){
$model = new User(['scenario' => 'register']);
}
}
?>
I have my own basic User model i reuse for most projects, which handles updating new password or leaving the previous one if no password is provided by the update form. Also implements IdentityInterface so it can be used for login to the Application.
My basic User model:
<?php
namespace app\models;
use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface {
const SCENARIO_LOGIN = 'login';
const SCENARIO_CREATE = 'create';
const SCENARIO_UPDATE = 'update';
// We use $hash to save the hashed password we already have saved in the DB
public $hash;
public $password_repeat;
/**
* #inheritdoc
*/
public static function tableName() {
return 'user';
}
/**
* #inheritdoc
*/
public function scenarios() {
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['user', 'password'];
$scenarios[self::SCENARIO_CREATE] = ['user', 'password', 'password_repeat', 'email', 'authKey'];
$scenarios[self::SCENARIO_UPDATE] = ['user', 'password', 'password_repeat', 'email'];
return $scenarios;
}
/**
* #inheritdoc
*/
public function rules() {
return [
[['user'], 'string', 'max' => 45],
[['email'], 'string', 'max' => 45],
[['email'], 'email'],
[['password', 'password_repeat'], 'string', 'max' => 60],
[['authKey'], 'string', 'max' => 32],
[['user', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
[['user', 'password', 'password_repeat', 'email'], 'required', 'on' => self::SCENARIO_CREATE],
[['user', 'email'], 'required', 'on' => self::SCENARIO_UPDATE],
// Generate a random String with 32 characters to use as AuthKey
[['authKey'], 'default', 'on' => self::SCENARIO_CREATE, 'value' => Yii::$app->getSecurity()->generateRandomString()],
[['password'], 'compare', 'on' => self::SCENARIO_CREATE, 'skipOnEmpty' => true],
[['user'], 'unique'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels() {
return [
'id' => 'Id',
'user' => 'User',
'password' => 'Password',
'authKey' => 'AuthKey',
'email' => 'Email',
];
}
/**
* #inheritdoc
*/
public function beforeSave($insert) {
if (parent::beforeSave($insert)) {
if($insert) {
$this->password = Yii::$app->getSecurity()->generatePasswordHash($this->password);
}
else {
if(strlen($this->password) > 0) {
$this->password = Yii::$app->getSecurity()->generatePasswordHash($this->password);
}
else {
$this->password = $this->hash;
}
}
return true;
}
return false;
}
/**
* #inheritdoc
*/
public function afterFind() {
$this->hash = $this->password;
$this->password = '';
parent::afterFind();
}
/**
* #inheritdoc
*/
public static function findIdentity($id) {
return self::findOne($id);
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null) {
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
/**
* #inheritdoc
*/
public static function findByUsername($username) {
$model = static::findOne(['user' => $username]);
return $model;
}
/**
* #inheritdoc
*/
public function getId() {
return $this->getPrimaryKey();
}
/**
* #inheritdoc
*/
public function getAuthKey() {
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey) {
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password) {
return Yii::$app->getSecurity()->validatePassword($password, $this->hash);
}
}
This way you only need to use the corresponding scenario in your create, update and login actions:
$model->scenario = User::SCENARIO_LOGIN;
$model->scenario = User::SCENARIO_CREATE;
$model->scenario = User::SCENARIO_UPDATE;
I have a table in my DB called 'member' where I intend to store username, password and all other related info of a user and I want to use those username/password for login instead yii2's default User.php model. I have been trying for almost a day and modified the Member.php model but can't make it work. Every time I use my custom username/password from db, it says username or password is incorrect.
Can anyone please help me out? Thanks in advance. :)
FYI, I have no such field in member table such as authKey or accessToken. I have tried all the related stackoverflow posts but in vein.
Member.php Model
namespace app\models;
use Yii;
use yii\web\IdentityInterface;
class Member extends \yii\db\ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return 'member';
}
public function rules()
{
return [
[['username', 'password', 'first_name', 'last_name', 'role'], 'required'],
[['created_by_date', 'last_modified_by_date'], 'safe'],
[['username', 'password', 'role', 'created_by_id', 'last_modified_by_id'], 'string', 'max' => 50],
[['first_name', 'last_name', 'middle_name', 'phone', 'mobile'], 'string', 'max' => 100],
[['email'], 'string', 'max' => 250],
[['address_line1', 'address_line2', 'address_line3'], 'string', 'max' => 512]
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'password' => 'Password',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'middle_name' => 'Middle Name',
'email' => 'Email',
'phone' => 'Phone',
'mobile' => 'Mobile',
'address_line1' => 'Address Line1',
'address_line2' => 'Address Line2',
'address_line3' => 'Address Line3',
'role' => 'Role',
'created_by_id' => 'Created By ID',
'created_by_date' => 'Created By Date',
'last_modified_by_id' => 'Last Modified By ID',
'last_modified_by_date' => 'Last Modified By Date',
];
}
public static function find()
{
return new MemberQuery(get_called_class());
}
public static function findIdentity($id)
{
$dbUser = self::find()
->where([
"id" => $id
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
public static function findIdentityByAccessToken($token, $userType = null)
{
$dbUser = self::find()
->where(["accessToken" => $token])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
public static function findByUsername($username)
{
$dbUser = self::find()
->where(["username" => $username])
->one();
if (!count($dbUser)) {
return null;
}
return $dbUser;
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->authKey;
}
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
config/web.php
'user' => [
'identityClass' => 'app\models\Member',
'enableAutoLogin' => true,
],
I didnt change the User.php model. Here it is:
namespace app\models;
class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'admin',
'authKey' => 'test100key',
'accessToken' => '100-token',
],
'101' => [
'id' => '101',
'username' => 'demo',
'password' => 'demo',
'authKey' => 'test101key',
'accessToken' => '101-token',
],
];
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
foreach (self::$users as $user) {
if ($user['accessToken'] === $token) {
return new static($user);
}
}
return null;
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
}
}
return null;
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
You should make sure you change the getUser() method on models/LoginForm.php to use your Member model class, otherwise it will keep validating against the default User model.
public function getUser() {
if ($this->_user === false) {
$this->_user = Member::findByUsername($this->username);
}
return $this->_user;
}
Also, here is an example of my own User model class
namespace app\models;
use Yii;
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface {
const SCENARIO_LOGIN = 'login';
const SCENARIO_CREATE = 'create';
public static function tableName() {
return 'user';
}
public function scenarios() {
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['username', 'password'];
$scenarios[self::SCENARIO_CREATE] = ['username', 'password', 'authKey'];
return $scenarios;
}
public function rules() {
return [
[['username', 'email'], 'string', 'max' => 45],
[['email'], 'email'],
[['password'], 'string', 'max' => 60],
[['authKey'], 'string', 'max' => 32],
[['username', 'password', 'email'], 'required', 'on' => self::SCENARIO_CREATE],
[['authKey'], 'default', 'on' => self::SCENARIO_CREATE, 'value' => Yii::$app->getSecurity()->generateRandomString()],
[['password'], 'filter', 'on' => self::SCENARIO_CREATE, 'filter' => function($value) {
return Yii::$app->getSecurity()->generatePasswordHash($value);
}],
[['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
[['username'], 'unique'],
[['email'], 'unique'],
[['authKey'], 'unique'],
];
}
public function attributeLabels() {
return [
'id' => 'Id',
'username' => 'Username',
'password' => 'Password',
'email' => 'Email',
'authKey' => 'authKey',
];
}
public static function findIdentity($id) {
return self::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null) {
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public static function findByUsername($username) {
return static::findOne(['username' => $username]);
}
public function getId() {
return $this->getPrimaryKey();
}
public function getAuthKey() {
return $this->authKey;
}
public function validateAuthKey($authKey) {
return $this->authKey === $authKey;
}
public function validatePassword($password) {
return Yii::$app->getSecurity()->validatePassword($password, $this->password);
}
}
Make sure the methods from IdentityInterface you implement but don't want to use throw an exception, just like i do on the findIdentityByAccessToken method.
You should extend User class with your Member class and set in main config:
[...]
'modules' => [
'user' => [
'class' => 'member class
'modelMap' => [
'User' => 'app\models\member',
More info: yii 2 : override user model
This is my validatePassword function in models/user.php
public function validatePassword($password)
{
/* var_dump(Yii::$app->getSecurity()->validatePassword($password, $this->password)); */
return Yii::$app->getSecurity()->validatePassword($password, $this->password);
};
this is my setPassword function in models/user.php
public function setPassword($password)
{
$this->password = Yii::$app->getSecurity()->generatePasswordHash($password);
}
to call setPassword function I use following beforeSave function in models/user.php:
public function beforeSave($insert) {
$this->setPassword($this->password);
$this->generateAuthKey();
$this->generatePasswordResetToken();
return true;
}
model rules models/user.php
public function rules()
{
return [
[['username', 'password', 'role'], 'required'],
[['username', 'password'], 'string', 'max' => 45],
[['role'], 'string', 'max' => 16],
[['auth_key'], 'string', 'max' => 32],
[['password_reset_token'], 'string', 'max' => 255],
[['username'], 'unique']
];
}
Why is the validation of my password always false?
I think you made a mistake in the database. Perhaps, your password field has VARCHAR(32) (you wrote "it's normal when i used md5 password.").
Yii::$app->getSecurity()->generatePasswordHash($password);
This function generates the string is longer than 32 characters. For the password field, use the TEXT instead of VARCHAR(32).
maybe you can see how to login in yii2 on http://www.bsourcecode.com/yiiframework2/yii-2-user-login-from-database/ or another stackoverflow question Yii Framework 2.0 Login With User Database
hope could help you..
Is $this->password equal with db value when validatePassword performing?
I believe setPassword() worked for $this->password before validatePassword.
I'm trying to learn yii 2.0 by creating a simple form for adding new posts.
Here's the respective method in my SiteController (have also added use app\models\Posts; at the top):
public function actionSave($id=NULL){
if($id = NULL)
$model = new Posts;
else
$model = $this->loadModel($id);
if(isset($_POST['Posts'])){
$model->load($_POST);
if($model->save()){
Yii::$app->session->setFlash('success', 'Model has been saved');
$this->redirect($this->createUrl('site/save', ['id' => $model->id]));
}else
Yii::$app->session->setFlash('error', 'Model could not be saved');
}
echo $this->render('save', ['model' => $model]);
}
It renders save view file. Here's that view file:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['class' => 'form-horizontal', 'role' => 'form']]) ?>
<div class="form-group">
<?php echo $form->field($model, 'title')->textInput(['class' => 'form-control']); ?>
</div>
<div class="form-group">
<?php echo $form->field($model, 'data')->textArea(['class' => 'form-control']); ?>
</div>
<?php echo Html::submitButton('Submit', ['class' => 'btn btn-primary pull-right']); ?>
<?php ActiveForm::end();
I'm expecting a form, but it's showing an error Calling unknown method: yii\db\ActiveQuery::formName()
What am i doing wrong here?
public function actionSave($id=NULL){
if($id == NULL)
$model = new Posts;
else
$model = $this->loadModel($id);
if(isset($_POST['Posts'])){
$model->load($_POST);
if($model->save()){
Yii::$app->session->setFlash('success', 'Model has been saved');
//Updated
$this->redirect(['save', 'id' =>$model->id]);
//Remove this
//$this->redirect($this->createUrl('site/save', ['id' => $model->id]));
}else
Yii::$app->session->setFlash('error', 'Model could not be saved');
}
echo $this->render('save', ['model' => $model]);
}
I suppose you use the loadModel function, if so, change this line
$model = Posts::find($id);
to this
$model = Posts::find()->where(['id' => $id])->one();
The error occurs because the object returned by loadModel is a ActiveQuery and the ActiveForm expected a ActiveRecord.
Calling unknown method: frontend\models\SignupForm::save()
SiteController.php
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$fileName = $model->username;
$model->file =UploadedFile::getInstance($model,'file');
$model->file->saveAs('uploads/'.$fileName.'.'.$model->file->extension );
$model->filePath = 'uploads/'.$fileName.'.'.$model->file->extension ;
$model->save();
return $this->redirect(['view', 'id' => $model->idQuiz]);
//}
// 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,
]);
}
signup.php
<?= $form->field($model, 'file')-> fileinput(); ?>
SignupForm.php
<?php
namespace frontend\models;
use common\models\User;
use yii\base\Model;
use Yii;
/**
* Signup form
*/
class SignupForm extends Model
{
public $username;
public $email;
public $password;
public $first_name;
public $last_name;
public $address;
public $state_id;
public $city_id;
public $file;
public $filePath;
/**
* #inheritdoc
*/
public function rules()
{
return [
['username', 'filter', 'filter' => 'trim'],
['username', 'required'],
['first_name', 'required'],
['last_name', 'required'],
['address', 'required'],
['state_id', 'required'],
['city_id', 'required'],
['filePath', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'filter', 'filter' => 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
];
}
/**
* Signs user up.
*
* #return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->first_name = $this->first_name;
$user->last_name = $this->last_name;
$user->address = $this->address;
$user->state_id = $this->state_id;
$user->city_id = $this->city_id;
$user->filePath = $this->filePath;
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
return $user->save() ? $user : null;
}
}