Get id number from signup form in yii2 advance

Hello I’m new here. I want to know how to get the id from sign up form? the signup form only can get the username, email and password. which i want to use the primary key user id connect with other table.

id column of the user is defined when the new record is inserted into the table.
You can access id after you have saved the model.

    public function actionCreate()
    {
          /* @var User $user */
        $model = new User();
        $model->scenario = 'signup';

        $otherModel = new OtherModel();

        if ($model->load(Yii::$app->request->post())) {
            // $otherModel->userId = $model->id;   // NG!!
            if ($model->validate()) {
                ...
                $model->save(false);
                $otherModel->userId = $model->id;   // OK!!
                ...
            }
        }
        return $this->render('create', [
            'model' => $model,
        ]);
    }

The model id is undefined. When use in SiteController.php. I am using yii2 advanced frontend signup.

SiteController.php

public function actionSignup()
    {
        $model = new SignupForm();
        $model2 = new Doc();
        if ($model->load(Yii::$app->request->post()) && $model->signup() && $model2->load(Yii::$app->request->post())) {
            
            
            if($model->validate()){
                $model->save(false);
                $model2->Id = $model->id; //this id is undefined
                $model2->save();
            }
        
            Yii::$app->session->setFlash('success', 'Thank you for registration. Please check your inbox for verification email.');
            return $this->goHome();
        }

        return $this->render('signup', [
            'model' => $model,
            'model2' => $model2,
        ]);
    }```


SignupForm.php

public function signup()
    {
        if (!$this->validate()) {
            return false;
        }
        
        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->generateEmailVerificationToken();

        return $user->save() && $this->sendEmail($user);
    }

signup.php

 <div class="row">
        <div class="col-lg-5">
            <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>

                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

                <?= $form->field($model2, 'docName')->textInput(['maxlength' => true]) ?>

                <?= $form->field($model, 'email') ?>

                <?= $form->field($model, 'password')->passwordInput() ?>

                <div class="form-group">
                    <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
                </div>

            <?php ActiveForm::end(); ?>
        </div>
    </div>

I see.

I would modify SignupForm to meet the needs.

  1. Add docName field to SignupForm
  2. Modify SingupForm::signup() method to save not only User model but also Doc model.
class SignupForm extends Model
{
    public $username;
    public $email;
    public $password;
    public $docName;

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            ...
            ['docName', 'required'],
            ['docName', 'string'],
        ];
    }

    public function signup()
    {
        if (!$this->validate()) {
            return false;
        }
        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->generateEmailVerificationToken();
        if ($user->save()) {
           $doc = new Doc();
           $doc->docName = $this->docName;
           $doc->Id = $user->id;
           if ( $doc->save() ) {
               return $this->sendEmail($user);
           }
      }
      return false;
  }
public function actionSignup()
    {
        $model = new SignupForm();
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
            Yii::$app->session->setFlash('success', 'Thank you ...');
            return $this->goHome();
        }
        return $this->render('signup', [
            'model' => $model,
        ]);
    }
<div class="row">
        <div class="col-lg-5">
            <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>
                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
                <?= $form->field($model, 'docName')->textInput(['maxlength' => true]) ?>
                <?= $form->field($model, 'email') ?>
                <?= $form->field($model, 'password')->passwordInput() ?>
                <div class="form-group">
                    <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
                </div>
            <?php ActiveForm::end(); ?>
        </div>
    </div>

still not work.

the docName is from different table which I call $model2. which the table consist of docName, docNumber and foreign key id. I actually want retrieve the user signup id to insert into the foreign key.

Yes, I know that.

signupForm model is not a directly related model to user table. As you see in signup() method, you have to use User model to save the data into user table. So you could use signupForm model and its singup() method to save some data into doc table.

You could modify the signup() method to return the id of the inserted user and the result of true/false. But IMO saving Doc model in singup() method might be more simple.

Probably you just have to specify the namespace of Doc model.

use \abc\xyz\Doc
...
        if ($user->save()) {
           $doc = new Doc();
           ...

or

        if ($user->save()) {
           $doc = new \abc\xyz\Doc();

Already try it, but still not save the id user to id foreign key of doc table. have try to run it and will it save to other tabel?

this is the update code

<?php

namespace backend\models;

use Yii;
use yii\base\Model;
use common\models\User;
use backend\models\Doc;

/**
 * Signup form
 */
class SignupForm extends Model
{
    public $username;
    public $email;
    public $password;

    public $docName;


    /**
     * {@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' => Yii::$app->params['user.passwordMinLength']],

        ];
    }

    /**
     * Signs user up.
     *
     * @return bool whether the creating new account was successful and email was sent
     */
    public function signup()
    {
        if (!$this->validate()) {
            return false;
        }

        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->generateEmailVerificationToken();

        if ($user->save() && $this->sendEmail($user)) {
            $userId = $user->getId(); // Retrieve the ID of the saved user
            $doc = new Doc();
            $doc->docName = $this->docName;
            $doc->id = $userId;
            return true;
        } else {
            // ... handle the case when user registration fails ...
            return false;
        }
    }

    /**
     * Sends confirmation email to user
     * @param User $user user model to with email should be send
     * @return bool whether the email was sent
     */
    protected function sendEmail($user)
    {
        return Yii::$app
            ->mailer
            ->compose(
                ['html' => 'emailVerify-html', 'text' => 'emailVerify-text'],
                ['user' => $user]
            )
            ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
            ->setTo($this->email)
            ->setSubject('Account registration at ' . Yii::$app->name)
            ->send();
    }
}
<?php

/** @var yii\web\View $this */
/** @var yii\bootstrap5\ActiveForm $form */
/** @var \backend\models\SignupForm $model */

use yii\bootstrap5\Html;
use yii\bootstrap5\ActiveForm;

$this->title = 'Signup';
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="site-signup">
    <h1><?= Html::encode($this->title) ?></h1>

    <p>Please fill out the following fields to signup:</p>

    <div class="row">
        <div class="col-lg-5">
            <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>

                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

                <?= $form->field($model, 'email') ?>

                <?= $form->field($model2, 'docName')->textInput(['maxlength' => true]) ?>

                <?= $form->field($model, 'password')->passwordInput() ?>

                <div class="form-group">
                    <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
                </div>

            <?php ActiveForm::end(); ?>
        </div>
    </div>
</div>

<?php

namespace backend\controllers;

use common\models\LoginForm;
use Yii;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\base\InvalidArgumentException;
use yii\web\BadRequestHttpException;
use frontend\models\VerifyEmailForm;
use backend\models\SignupForm;
use common\models\User;
use backend\models\Doc;

/**
 * Site controller
 */
class SiteController extends Controller
{
    /**
     * {@inheritdoc}
     */
public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'only' => ['create', 'update','index'],

                'rules' => [
                    [
                        'actions' => ['login', 'error'],
                        'allow' => true,
                    ],
                    [
                        'actions' => ['logout', 'index'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
        ];
    }


    /**
     * {@inheritdoc}
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => \yii\web\ErrorAction::class,
            ],
        ];
    }

    /**
     * Displays homepage.
     *
     * @return string
     */
    public function actionIndex()
    {
        return $this->render('index');
    }

    /**
     * Login action.
     *
     * @return string|Response
     */
    public function actionLogin()
    {
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $this->layout = 'main';

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        }

        $model->password = '';

        return $this->render('login', [
            'model' => $model,
        ]);
    }


    public function actionSignup()
    {
        $model = new SignupForm();
        $model2 = new Doc();
       
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
                Yii::$app->session->setFlash('success', 'Thank you for registration. Please check your inbox for verification email.');
                return $this->goHome();
            
        }

        return $this->render('signup', [
            'model' => $model,
            'model2' => $model2,
        ]);
    }

    public function actionVerifyEmail($token)
    {
        try {
            $model = new VerifyEmailForm($token);
        } catch (InvalidArgumentException $e) {
            throw new BadRequestHttpException($e->getMessage());
        }
        if (($user = $model->verifyEmail()) && Yii::$app->user->login($user)) {
            Yii::$app->session->setFlash('success', 'Your email has been confirmed!');
            return $this->goHome();
        }

        Yii::$app->session->setFlash('error', 'Sorry, we are unable to verify your account with provided token.');
        return $this->goHome();
    }


    /**
     * Logout action.
     *
     * @return Response
     */
    public function actionLogout()
    {
        Yii::$app->user->logout();

        return $this->goHome();
    }
}

<?php

namespace backend\models;

use Yii;

/**
 * This is the model class for table "doc".
 *
 * @property int $docId
 * @property string $docName
 * @property int $id
 *
 * @property User $id0
 */
class Doc extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'doc';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['docName', 'id'], 'required'],
            [['id'], 'integer'],
            [['docName'], 'string', 'max' => 255],
            [['id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['id' => 'id']],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'docId' => 'Doc ID',
            'docName' => 'Doc Name',
            'id' => 'ID',
        ];
    }

    /**
     * Gets query for [[Id0]].
     *
     * @return \yii\db\ActiveQuery
     */
    public function getId0()
    {
        return $this->hasOne(User::class, ['id' => 'id']);
    }
}

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/** @var yii\web\View $this */
/** @var backend\models\Doc $model */
/** @var yii\widgets\ActiveForm $form */
?>

<div class="doc-form">

    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'docName')->textInput(['maxlength' => true]) ?>

    <?= $form->field($model, 'id')->textInput() ?>

    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

  1. You have to set the validation rules for SignupForm::docName
    public function rules()
    {
        return [
            ['username', 'trim'],
            ...
            ['docName', 'required'],
            ['docName', 'string', ...],
        ];
    }
  1. Use only SignupForm model (i.e., without Doc model) in the controller and the view.
    public function actionSignup()
    {
        $model = new SignupForm();
        // $model2 = new Doc();
       
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
                Yii::$app->session->setFlash('success', 'Thank you for registration. Please check your inbox for verification email.');
                return $this->goHome();
        }

        return $this->render('signup', [
            'model' => $model,
            // 'model2' => $model2,
        ]);
    }
                <?= $form->field($model, 'docName')->textInput(['maxlength' => true]) ?>

Thank you. It work already. I have to copy the User model to frontend.