Yii2 Automatically Login after Registration - yii2

I'm creating a website using yii2 framework. I have a problem in registration. I have a modal in home and it contains the sign up form. Now when i trying to register, Yes it saved successful but it only stay in the modal. Now i want is after registering it will automatically login.
This is my sign up form_:
<div class="row">
<div class="col-lg-12">
<?php yii\widgets\Pjax::begin(['id' => 'sign-up']) ?>
<?php $form = ActiveForm::begin(['id' => 'form-signup', 'options' => ['data-pjax' => true]]); ?>
<div class="row">
<div class="col-sm-6">
<?= $form->field($model, 'role')->dropDownList(['2' => 'User', '1' => 'Encoder', '3' => 'Admin']) ?>
<?= $form->field($model, 'username')->textInput(['placeholder' => 'Username....']) ?>
<?= $form->field($model, 'email')->textInput(['placeholder' => 'Email....']) ?>
<?= $form->field($model, 'password')->passwordInput(['placeholder' => 'Password.....']) ?>
</div>
<div class="col-sm-6">
<?= $form->field($model, 'confirmPassword')->passwordInput(['placeholder' => 'Confirm Password.....']) ?>
<?= $form->field($model, 'first_name')->textInput(['placeholder' => 'First Name....']) ?>
<?= $form->field($model, 'middle_name')->textInput(['placeholder' => 'Middle Name....']) ?>
<?= $form->field($model, 'last_name')->textInput(['placeholder' => 'Last Name....']) ?>
</div>
</div>
<center>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className()) ?>
</center>
<div class="form-group">
<?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button', 'style' => 'width: 100%; padding: 10px;']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php yii\widgets\Pjax::end() ?>
</div>
</div>
This is my model:
class SignupForm extends Model
{
public $role;
public $username;
public $email;
public $password;
public $first_name;
public $middle_name;
public $last_name;
public $confirmPassword;
public $verifyCode;
public function rules()
{
return [
['role', 'required'],
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 20],
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 30],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
['first_name', 'trim'],
['first_name', 'required'],
['middle_name', 'trim'],
['middle_name', 'required'],
['last_name', 'trim'],
['last_name', 'required'],
['verifyCode', 'captcha'],
['verifyCode', 'required'],
[['confirmPassword'], 'compare', 'compareAttribute' => 'password', 'message' => 'Passwords do not match.'],
];
}
/**
* 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->role = $this->role;
$user->first_name = $this->first_name;
$user->middle_name = $this->middle_name;
$user->last_name = $this->last_name;
return $user->save() ? $user : null;
}
}
This is my 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->renderAjax('signup', [
'model' => $model,
]);
}
I don't have any ideas, I think my codes is correct but i don't know why is not working.
UPDATED
When i clicked the button signup it stay only in the modal and when i clicked it again the button the validations is working. It means it saves to database but not automatically login.

you should get the user identity for login
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
$identity = User::findOne(['username' => $model->$username]);
if (Yii::$app->user->login($identity)) {
return $this->goHome();
}
}
}
return $this->renderAjax('signup', [
'model' => $model,
]);
}
see this for more http://www.yiiframework.com/doc-2.0/guide-security-authentication.html
http://www.yiiframework.com/doc-2.0/yii-web-user.html

I have used below code and its working for me . Its also a standard code for YII2 .Controller Action Code :
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
$model= \common\models\User::findOne([$user->id]); //you need to get complete model again and pass it to login function
if (Yii::$app->user->login($model) {
return $this->goHome();
}
}
}
return $this->renderAjax('signup', [
'model' => $model,
]);
}

After couple minutes of step by step debug - it works well
//Signup
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post()) && $model->signup()) { /*Save
to DB first*/
$genmail = $model->email; //get model email value
$identity = User::findOne(['email' => $genmail]); //find user by email
if (Yii::$app->user->login($identity)) { // login user
return $this->redirect('account'); // show accaount page
}
}
return $this->render('signup', [
'model' => $model,
]);
}

Related

Validate checked checkbox quantity

I have a voting form and I would like to validate the minimum and maximum number of candidates that each voter can vote for. These max and min values are stored in the logged user's session. What better way to do it?
MODEL Voto.php
public static function tableName()
{
return 'voto';
}
public function rules()
{
return [
[['eleicao_id', 'candidato_id', 'cargo_id', 'urna_id', 'created'], 'required','message'=> 'Selecione no mínimo 1 candidato!'],
[['eleicao_id', 'cargo_id', 'urna_id'], 'integer'],
[['created','candidato_id'], 'safe'],
[['eleitor_hash'], 'string', 'max' => 255],
];
}
FORM _form_votacao.php
<?php $form = ActiveForm::begin(); ?>
<div class="row">
<?php
$candidato = ArrayHelper::map(candidato::find()
->where(['status' => 1])
->Andwhere(['eleicao_id' => Yii::$app->user->identity->eleicao_id])
->orderBy("nome ASC")
->all(), 'id', 'nome'
);
echo $form->field($model, 'candidato_id')->checkboxList($candidato, [
'class' => 'h4',
'data-toggle' => 'button',
'item' => function($index, $label, $name, $checked, $value) {
return "<label class='col-md-5'><input type='checkbox' {$checked} name='{$name}' value='{$value}'> {$label}</label>";
}])->label(false);
?>
</div>
<br>
<div class="row text-center">
<div class="form-group">
<?= Html::submitButton('Confirmar', ['class' => 'btn btn-success']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
Note: This list of candidates is dynamic, loads the candidates according to the parameters of the user logged in.
Rules Test UPDATE:
public function rules()
{
return [
['candidato_id', 'validateCandidates','message'=> 'teste'],
];
}
public function validateCandidates($attribute, $params, $validator){
if(count($this->candidato_id) >= 4){ // test with value 4
$this->addError($attribute, 'Error message');
}
}
Create custom validation. Something like this:
Model Voto.php
public function rules()
{
return [
....
['candidato_id', 'validateCandidates'],
....
];
}
public function validateCandidates($attribute, $params, $validator){
if(count($this->candidato_id) < {session_min} and count($this->candidato_id) > {session_max}){
$this->addError($attribute, 'Error message');
}
}

Yii2 create or update user profile

In my basic app, I have a User model and a UserForm model that stores and update the users in the database. Now, I got problem when updating the user profile. It feedbacks 'Successful update!' even though the new data won't save.
My table:
Table name: User
Attributes: id, fname, mname, lname, address, username, auth_key, password_hash, password_reset_token, email, status, created_at, updated_at
My Model:
class UserForm extends Model
{
public $fname;
public $mname;
public $lname;
public $address;
public $username;
public $email;
public $password_hash;
/**
* #inheritdoc
*/
public function rules()
{
return [
['fname', 'required'],
['fname', 'trim'],
['mname', 'trim'],
['lname', 'required'],
['lname', 'trim'],
['address', 'required'],
['address', 'trim'],
['address', 'string', 'max' => 255],
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 4, 'max' => 255],
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This email address has already been taken.'],
['password_hash', 'required', 'on' => 'insert'],
['password_hash', 'string', 'min' => 8],
];
}
public function beforeSave($insert) {
if ($insert) {
$this->setPassword($this->password_hash);
} else {
if (!empty($this->password_hash)) {
$this->setPassword($this->password_hash);
} else {
$this->password_hash = (string) $this->getOldAttribute('password_hash');
}
}
return parent::beforeSave($insert);
}
}
My controller:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->setAttribute('password_hash', null);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
Yii::$app->session->setFlash('success', Yii::t('app', 'Successful update!'));
return $this->redirect(['overview']);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
protected function findModel($id) {
if (($model = User::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
My view.php
<?= $form->field($model, 'fname')->textInput(['autofocus' => true])->label('First Name') ?>
<?= $form->field($model, 'mname')->textInput()->label('Middle Name') ?>
<?= $form->field($model, 'lname')->textInput()->label('Last Name') ?>
<?= $form->field($model, 'address')->textInput() ?>
<?= $form->field($model, 'username')->textInput() ?>
<?= $form->field($model, 'email') ?>
<?= $form->field($model, 'password_hash')->passwordInput(['placeholder' => Yii::t('app', 'Password'), 'value' => ''])->label(false) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
Some of the steps are from here: yii2 user CRUD create or update with password
Your UserForm is never used. Your findModel() returns User, so all validation and saving is handled by User model - I guess it does not have any validation rules, so $model->load() does not load anything.
You may try to extend your form model from active record model:
class UserForm extends User
And use it in findModel() or create separate method for returning form model:
protected function findFormModel($id) {
if (($model = UserForm::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
Then use this method in your update action. Don't forget to remove old properties from UserForm - they're unnecessary and may break attributes behavior.

Yii2 multiple upload on another model

I need help building a simple protocol form with multiple attachments, where the user can change these attachments (files) later. That is, the attachments must have binding to a protocol.
(In this case I created 2 tables: mod_protocol and mod_files)
How should my code stay so that when I insert a new form, the attachments of this form are written to the mod_files table? (I'm not sure how to build a loop to write the files)
I'm at the beginning of this project, check out my files:
protocol form
<div class="protocol-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'description')->textarea(['rows' => 8]) ?>
<?= $form->field($model, 'files[]')->fileInput(['multiple' => true,]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Save' : 'Save', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
protocol model
<?php
namespace app\modules\protocol\models;
use Yii;
class Protocol extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'mod_protocol';
}
public function rules()
{
return [
[['name'], 'required'],
[['name','description'], 'string', 'max' => 200],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nome',
'description' => 'Descrição'
];
}
}
protocol controlller
public function actionCreate()
{
$model = new Protocol();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
files model
<?php
namespace app\modules\protocol\models;
use Yii;
class Files extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'mod_files';
}
public function rules()
{
return [
[['filename','protoco_id'], 'safe'],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'filename' => 'Nome do Arquivo',
'protoco_id' => 'Protocolo'
];
}
}
So if file is an array:
use yourapp/model/ModFile;
...
public function actionCreate()
{
$model = new Protocol();
// I would write some logic, verify this saves first.
foreach($model->files as $file) {
$model_file = new ModFile();
$model_file->file = $file;
$model_file->save();
}
// If successful then save the main model.
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}

Yii2 log in form works only when ajaxvalidation is false

I have a log in form which works only when i turn of my ajaxValidation. If i enable itenableAjaxValidation = true` it dies. What is the problem? Is it something with the model rules? On the previous projects i used the same form and all was fine. Can't realize. Can you guys give an advice and quick explanation. Thank you in advance!
<div class="row">
<div class="col-xs-12">
<h3 class="contact-page-title"><?= Yii::t('app', 'app.Login') ?></h3>
<?php if (Yii::$app->user->isGuest): ?>
<?php $form = ActiveForm::begin([
'id' => 'login-widget-form',
'action' => Url::to(['/user/security/login']),
/*'enableAjaxValidation' => true,*/
'enableClientValidation' => false,
'validateOnBlur' => false,
'validateOnType' => false,
'validateOnChange' => false,
]) ?>
<?= $form->field($model, 'login')->textInput() ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'rememberMe')->checkbox() ?>
<input type="hidden" name="checkoutLogin" value="1">
<?= Html::submitButton(Yii::t('user', Yii::t('app','app.Login')) , ['class' => 'btn-1 shadow-0 full-width']) ?>
<?php ActiveForm::end(); ?>
<?php else: ?>
<?= Html::a(Yii::t('user', 'Logout'), ['/user/security/logout'], [
'class' => 'btn btn-danger btn-block',
'data-method' => 'post'
]) ?>
<?php endif ?>
</div>
</div>
And these are the rules:
public function rules()
{
$rules = [
'loginTrim' => ['login', 'trim'],
'requiredFields' => [['login'], 'required'],
'confirmationValidate' => [
'login',
function ($attribute) {
if ($this->user !== null) {
$confirmationRequired = $this->module->enableConfirmation
&& !$this->module->enableUnconfirmedLogin;
if ($confirmationRequired && !$this->user->getIsConfirmed()) {
$this->addError($attribute, Yii::t('user', 'You need to confirm your email address'));
}
if ($this->user->getIsBlocked()) {
$this->addError($attribute, Yii::t('user', 'Your account has been blocked'));
}
}
}
],
'rememberMe' => ['rememberMe', 'boolean'],
];
if (!$this->module->debug) {
$rules = array_merge($rules, [
'requiredFields' => [['login', 'password'], 'required'],
'passwordValidate' => [
'password',
function ($attribute) {
if ($this->user === null || !Password::validate($this->password, $this->user->password_hash)) {
$this->addError($attribute, Yii::t('user', 'Invalid login or password'));
}
}
]
]);
}
return $rules;
}
EDIT Action:
public function actionLogin() {
if (!Yii::$app->user->isGuest) {
$this->goHome();
}
$register = new RegistrationForm();
if(Yii::$app->request->isAjax){
return 1;
}
/** #var LoginForm $model */
$model = Yii::createObject(LoginForm::className());
$event = $this->getFormEvent($model);
$this->performAjaxValidation($model);
$this->trigger(self::EVENT_BEFORE_LOGIN, $event);
if ($model->load(Yii::$app->getRequest()->post()) && $model->login()) {
$this->trigger(self::EVENT_AFTER_LOGIN, $event);
//return $this->goBack();
if (Yii::$app->request->baseUrl == "" and !isset($_POST["checkoutLogin"])) {
$session = Yii::$app->session;
return $this->redirect('/');
} elseif(isset($_POST["checkoutLogin"]) and $_POST["checkoutLogin"] == 1) {
$lang = \frontend\models\Lang::getCurrent();
$checkout = Page::findOne(91);
if($checkout){
return $this->redirect('/'.$lang->url.'/'.$checkout->url);
}else{
return $this->goBack();
}
} else {
return $this->goBack();
}
}
return $this->render('login', [
'model' => $model,
'module' => $this->module,
'register' => $register
]);
}
Try with the code of performAjaxValidation() moved to the action:
// instead of $this->performAjaxValidation($model);
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}

Yii2 Confirm Password not working

I am trying to build a signup form, it works fine when I dont use repeat password, it saves to the model, but when I use my repeat password it just does'nt let me save them in the database. My code is below.
SimUser.php file
public function rules()
{
return [
[['user_email', 'user_password_hash','company_id','user_fname', 'user_lname','agree'], 'required'],
['agree','required','requiredValue' => 1, 'message' => ''],
['user_password_hash_repeat', 'compare','compareAttribute' => 'user_password_hash','message' => 'Password don\'t match'],
[['agree'],'safe'],
[['user_password_hash_repeat'],'safe'],
[['user_company', 'user_suspended', 'user_deleted'], 'integer'],
[['user_created'], 'safe'],
[['user_email'], 'string', 'max' => 255],
[['user_password_hash'], 'string', 'max' => 72],
[['user_fname', 'user_lname'], 'string', 'max' => 45],
[['user_auth_key'], 'string', 'max' => 32],
[['user_access_token'], 'string', 'max' => 100],
];
}
My controller action: site/signup
public function actionSignup()
{
$company = new Company();
$company->load(Yii::$app->request->post());
$company->save();
$model = new SimUser();
if ($model->load(Yii::$app->request->post())) {
$model->setPassword($model->user_password_hash);
$model->generateAuthKey();
$model->company_id = $company->company_id;
//var_dump($model); exit();
$model->save();
$model = new LoginForm();
return $this->render('login',[
'model' => $model,
]);
}
return $this->render('signup', [
'model' => $model,
'company' => $company,
]);
}
Here I am saving the comany name in the company model and the others in the user table.
My views file: signup.php
<h1>Sign Up</h1>
<?= $form->field($model, 'user_fname')->textInput(['placeholder'=>'First Name*','class'=>'form-control col-lg-4'])->label(false);?>
<?= $form->field($model, 'user_lname')->textInput(['placeholder'=>'Last Name*','class'=>'form-control col-lg-4'])->label(false); ?>
<?= $form->field($model,'user_email')->textInput(['placeholder'=>'Email*','class'=>'form-control col-lg-4'])->label(false); ?>
<?= $form->field($model, 'user_password_hash')->passwordInput(['placeholder'=>'Password'])->label(false); ?>
<?= $form->field($model, 'user_password_hash_repeat')->passwordInput(['placeholder'=>'Confirm Password*','class'=>'form-control col-lg-4'])->label(false); ?>
<?= $form->field($company, 'company_name')->textInput(['placeholder'=>'Company Name*','class'=>'form-control col-lg-4'])->label(false); ?>
<?php echo $form->field($model, 'agree')->checkbox(); ?>
<div class="form-group">
<?= Html::submitButton('Sign Up', ['class' => 'pull-left padding-0 btn btn-success', 'name' => 'signup-button']) ?>
</div>
The error message for the company doesn't go, it is always there.. attached output as image
Can anyone of you help me solve this issue? Thanks in advance!!
Company.php
*/
public function rules()
{
return [
[['company_name'], 'required'],
[['company_name'], 'string', 'max' => 75],
];
}
In the controller have saved Company in the beginnig itself. So everytime, I load the page It is saving before I could submit it. Hence the error remains as it is.
Code to be changed:
$company = new Company();
$model = new SimUser(['scenario' => SimUser::SCENARIO_REGISTER]);
if ($model->load(Yii::$app->request->post()) && $company->load(Yii::$app->request->post())) {
$company->save();
$model->setPassword($model->user_password_hash);
$model->generateAuthKey();
$model->company_id = $company->company_id;
$model->save();
So 1 issue has been solved.. Unable to solve the confirm password issue! Would be helpful if someone can post what the mistake is?