```
declare(strict_types=1);

namespace app\models\forms;

use Yii;
use yii\base\Model;
use yii\base\InvalidArgumentException as YiiBaseInvalidArgumentException;
use yii\base\Exception as YiiBaseException;
use yii\db\Exception as YiiDbException;

use app\models\User;
use app\helpers\AppHelper;
use app\helpers\ErrorMessageHelper;
use app\helpers\ExceptionLogger;
use app\helpers\ParamHelper;
use app\helpers\RoleHelper;

class AccountEmailForm extends Model
{
	public string $password_old = '';
	public string $email;// Handled in __construct()
	public string $email_new = '';
	public string $email_repeat = '';
	
	private ?User $_user = null;
	
	private string $_appName;
	private string $_emailSupport;
	
        public function __construct(int $id, array $config = [])
        {
		$this->_user = User::findIdentity($id);
		
		if (!$this->_user)
		{
			$msg = \Yii::t('app', 'Unable to find account.');
			throw new YiiBaseInvalidArgumentException($msg);
		}
		
		$this->email = $this->_user->email;
		
		$this->_appName = AppHelper::name();
		$this->_emailSupport = ParamHelper::get('email.support');
		
		parent::__construct($config);
	}
	
	public function rules(): array
	{
		return [
			[['password_old', 'email_new', 'email_repeat'], 'required'],
			
			// Compare new email address matches repeat
			['email_repeat', 'compare', 'compareAttribute' => 'email_new', 'message' => 
				\Yii::t('app', 'Email addresses do not match.'),
			],
			
			// Validate email_new
			['email_new', 'trim'],
			['email_new', 'required'],
			['email_new', 'string', 'max' => 255],
			
			// Ensure email_new is NOT already taken by another active user
			['email_new', 'unique', 
				'targetClass' => User::class,
				'filter' => function ($query)
				{
					// TODO Exclude the current user's email when checking for uniqueness
					$query->active()->andWhere(['not', ['id' => $this->getUserId()]]);
					
					// @var $query \app\models\UserQuery
					//$query->active();
				},
				'message' => ErrorMessageHelper::genericFormError(),
				//'message' => Yii::t('app', 'This email address is already taken.'),
			],
			
			// Validate the old password via a custom method in the model
			['password_old', 'validatePassword'],
		];
	}
	
	public function attributeLabels(): array
	{
		return [
			'password_old' => \Yii::t('app', 'Password'),
			//'email' => \Yii::t('app', 'Account Email'),
			'email_new' => \Yii::t('app', 'New Email'),
			'email_repeat' => \Yii::t('app', 'Confirm Email'),
		];
	}
	
	public function validatePassword($attribute, $params)
	{
		if (!$this->hasErrors())
		{
			$validate = \Yii::$app->security->validatePassword(
				$this->password_old,
				$this->_user->password_hash
			);

			if (!$validate)
			{
				$msg = \Yii::t('app', 'Password is incorrect.');
				$this->addError($attribute, $msg);
			}
		}
	}
	
	public function process(): bool
	{
		$transaction = \Yii::$app->db->beginTransaction();
		try
		{
			$this->_user->email = $this->email_new;
			$this->_user->deactivateAccount();
			$this->_user->generateAuthKey();
			$this->_user->generateEmailVerificationToken();
			
			if (!$this->_user->save(false, ['email', 'status', 'auth_key', 'verification_token']))
			{
				throw new YiiDbException("Failed to save user data to the database.");
			}
			
			$transaction->commit();
			
			return $this->sendEmail();
		}
		catch (\Throwable $e)
		{
			// An error occurred; roll back the transaction.
			$transaction->rollBack();
			
			// Use the ExceptionLogger to handle and log the exception.
			ExceptionLogger::log($e, 'account_email_form_error_');
		}
		
		return false;
	}
	
	private function sendEmail(): bool
	{
		try
		{
			$isSent = \Yii::$app->mailer->compose(
					['html' => 'emailVerify-html', 'text' => 'emailVerify-text'],
					[
						'emailAppName' => $this->_appName,
						'emailSupport' => $this->_emailSupport,
						'emailUser' => $this->_user,
					]
				)
				->setFrom([$this->_emailSupport => \Yii::t(
					'appEmail',
					'{appName} robot',
					['appName' => $this->_appName])
				])
				->setTo($this->_user->email)
				->setSubject(\Yii::t(
					'appEmail',
					'New email address verification for {appName}',
					['appName' =>  $this->_appName])
				)
				->send();
			
			if (!$isSent)
			{
				throw new YiiBaseException("The email could not be sent to {$this->_user->email}.");
			}
			
			return true;
		}
		catch (\Throwable $e)
		{
			ExceptionLogger::log($e, 'account_email_form_sendmail_error_');
		}
		
		return false;
	}
}
```

account controller

```
class AccountController extends SeoController
{
	public function behaviors(): array
	{
		$behaviors = [];
		
		$behaviors['access'] = [
			'class' => AccessControl::class,
			'rules' => [
				[
					// User can do the following:
					'actions' => [
						'settings',
						'email',
					],
					'allow' => true,
					'roles' => ['@'],
				],
				[
					// Guest can't do the following:
					'actions' => [
						'settings',
						'email',
					],
					'allow' => false,
					'roles' => ['?'],
				],
			],
		];
		
		$behaviors['verbs'] = [
			'class' => VerbFilter::class,
			'actions' => [
				'settings' => ['get'],
				'email' => ['get', 'post'],
			],
		];
	}

	public function actionSettings(): Response|string
	{
		
		$user = $this->findModel($this->_userId);
		$modelEmail = new AccountEmailForm($user->id);
		
		return $this->render('settings', [
			'user' => $user,
			'modelEmail' => $modelEmail,
		]);
	}
	
	public function actionEmail(): Response|string
	{
		$user = $this->findModel($this->_userId);
		
		try
		{
			$model = new AccountNewsletterForm($user->id);
		}
		catch (YiiBaseInvalidArgumentException $e)
		{
			throw new YiiWebBadRequestHttpException($e->getMessage());
		}
		
		$request = \Yii::$app->request;
		if ($request->isPost)
		{
			if ($model->load($request->post()) && $model->validate())
			{
				if ($model->process())
				{
					$msg = \Yii::t(
						'app', 
						'<h4 class="alert-heading">Email Address Changed</h4>
						<p>Your email address has been successfully updated. Please check your inbox for further instructions.</p>'
					);
					\Yii::$app->session->setFlash('success', $msg);
				
					return $this->redirect(['account/settings']);
				}
				else
				{
					\Yii::$app->session->setFlash('error', ErrorMessageHelper::unexpectedError());
					
					return $this->redirect(['account/settings']);
				}
			}
		}
		
		return $this->redirect(['account/settings']);
	}
}
```

setting view

```
<?php
$form = ActiveForm::begin([
	'id' => 'account-email',
	'action' => ['account/email'],
	'method' => 'post',
]);
?>
<!--<div class="row mt-2 mb-2 p-2"> -->

<div class="col-md-12 mb-2">
<?= $form->field($modelEmail, 'password_old')->passwordInput([
	'class' => 'form-control square',
]); ?>
</div><!-- .col-md-12 .mb-2 -->

<div class="col-md-12 mb-2">
<?= $form->field($modelEmail, 'email_new')->textInput([
	'autofocus' => true,
	'class' => 'form-control square',
	'placeholder' => \Yii::t('app', 'Enter new email'),
]); ?>
</div><!-- .col-md-12 .mb-2 -->

<div class="col-md-12 mb-2">
<?= $form->field($modelEmail, 'email_repeat')->textInput([
	'class' => 'form-control square',
	'placeholder' => \Yii::t('app', 'Comfirm new email'),
]); ?>
</div><!-- .col-md-12 .mb-2 -->

<div class="m-2 p-2">
<p class="muted">
<?= \Yii::t(
	'app', 
	'A verification email will be sent upon completion. Your account will be disabled until the new email address is verified 
	to confirm account ownership.'
); ?>
</p>
</div><!-- .m-2 .p-2 -->


<div class="text-left col-12 col-md-auto">
<?= Html::submitButton(\Yii::t('app', 'change email address'), [
	'class' => 'btn btn-primary square w-100 w-md-auto',
	'name' => 'email-address-button',
]); ?>
</div><!-- .text-left .col-12 .col-md-auto -->


<!-- </div><!-- .row .mt-2 .mb-2 .p-2 -->
<?php ActiveForm::end(); ?>
```


what am i doing wrong? no errors, but also does not work.