using yii2. User model activeRecorder and NewsletterSubcriber activeRecorder. NewsletterSubscriber works with User:
```
class User extends ActiveRecord implements IdentityInterface, IpRateLimitInterface
{
	// Newsletter subscription
	const SUBSCRIPTION_INACTIVE = 9;
	const SUBSCRIPTION_ACTIVE = 10;
	
	public function rules(): array
	{
		return [
			['subscription', 'default', 'value' => self::SUBSCRIPTION_INACTIVE],
			['subscription', 'in', 'range' => [self::SUBSCRIPTION_INACTIVE, self::SUBSCRIPTION_ACTIVE]],
		];
	}
}
```

and
```
class NewsletterSubscriber extends ActiveRecord
{
	const STATUS_DELETED = 0;
	const STATUS_INACTIVE = 9;
	const STATUS_ACTIVE = 10;
	
	public function rules(): array
	{
		return [
			['status', 'default', 'value' => self::STATUS_INACTIVE],
			['status', 'in', 'range' => [self::STATUS_DELETED, self::STATUS_INACTIVE, self::STATUS_ACTIVE]],
		];
	}
	
	public function isSubscriber(string $email): NewsletterSubscriber|false
	{
		$subscriber = self::find()->where(['email' => $email, 'status' => self::STATUS_ACTIVE])->one();
		
		return $subscriber ?: false;
	}
	
	public function getSubscriberByEmail(string $email): ?self
	{
		return self::find()->where(['email' => $email])->one();
	}
	
	public function upsertSubscriber(string $email, int $status, ?int $userId = null): bool
	{
		$subscriber = self::find()->where(['email' => $email])->one();
		if ($subscriber === null)
		{
			return $this->createSubscriber($email, $status, $userId);
		}
		else
		{
			return $this->updateSubscriber($email, $status, $userId);
		}
	}
	
	protected function createSubscriber(string $email, int $status, ?int $userId = null): bool
	{
		$transaction = \Yii::$app->db->beginTransaction();
		try
		{
			$user = null;
			
			// If user exist... 
			if ($userId !== null)
			{
				$user = User::findOne($userId);
				
				// User must exist if userId provided
				if (!$user)
				{
					return false;
				}
				
				// Sync user subscription to $status if different
				if ($user->subscription !== $status)
				{
					$user->subscription = $status;
					if (!$user->save(false, ['subscription']))
					{
						throw new YiiDbException('Failed to save user data to database.');
					}
				}
			}
			
			// Check if subscriber already exists — fail if it does
			$subscriber = self::find()->where(['email' => $email])->one();
			
			// Subscriber exists, creation fails
			if ($subscriber !== null)
			{
				return false;
			}
			
			// Create new subscriber
			$subscriber = new self();
			$subscriber->email = $email;
			$subscriber->generateSubscriberToken();
				
			// Use User subscription if User exists, else passed $status
			$subscriber->status = $user ? $user->subscription : $status;
			
			// If $userId is not null and user exist and ids match...
			if ($user !== null && $userId === $user->id)
			{
				$subscriber->user_id = $userId;
			}
			
			// This could include 'user_id' or not, depending on if they existed or not...
			if (!$subscriber->save(false))
			{
				throw new YiiDbException('Failed to save user subscriber data to database.');
			}
			
			// If all saves are successful, commit the transaction.
			$transaction->commit();
			
			return true;
		}
		catch (\Throwable $e)
		{
			// An error occurred; roll back the transaction.
			$transaction->rollBack();
			
			// Use the ExceptionLogger to handle and log the exception.
			ExceptionLogger::log($e, 'newsletter_create_subscriber_model_error_');
		}
		
		return false;
	}
	
	protected function updateSubscriber(string $email, int $status, ?int $userId = null): bool
	{
		$transaction = \Yii::$app->db->beginTransaction();
		try
		{
			$user = null;
			
			// If user exist... 
			if ($userId !== null)
			{
				$user = User::findOne($userId);
				
				// User must exist if userId provided
				if (!$user)
				{
					return false;
				}
				
				// Sync user subscription to $status if different
				if ($user->subscription !== $status)
				{
					$user->subscription = $status;
					if (!$user->save(false, ['subscription']))
					{
						throw new YiiDbException('Failed to save user data to database.');
					}
				}
			}
			
			// Check if subscriber already exists — fail if it does not
			$subscriber = self::find()->where(['email' => $email])->one();
			
			// Subscriber missing — update fails
			if ($subscriber === null)
			{
				return false;
			}
			
			// Sync subscriber status with User subscription if User exists
			if ($user !== null && $subscriber->status !== $user->subscription)
			{
				$subscriber->status = $user->subscription;
			}
			elseif ($subscriber->status !== $status)
			{
				$subscriber->status = $status;
			}
			
			// Link user_id if missing and valid
			if ($subscriber->user_id === null && $user !== null && $userId === $user->id)
			{
				$subscriber->user_id = $userId;
			}
			
			// This could include 'user_id' or not, depending on if they existed or not...
			if (!$subscriber->save(false))
			{
				throw new YiiDbException('Failed to save subscriber data to database.');
			}
			
			// If all saves are successful, commit the transaction.
			$transaction->commit();
			
			return true;
		}
		catch (\Throwable $e)
		{
			// An error occurred; roll back the transaction.
			$transaction->rollBack();
		
			// Use the ExceptionLogger to handle and log the exception.
			ExceptionLogger::log($e, 'newsletter_update_subscriber_model_error_');
		}
		
		return false;
	}
}
```

User $user->subscription trumps the newsletter subscriber models status, if user exists, if not we fallback to newsletter subscriber only.
Trying to create a account setting that turns on and off this feature:

```
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\models\NewsletterSubscriber;
use app\helpers\ExceptionLogger;

class AccountNewsletterForm extends Model
{
	public int $subscription;
	
	// @var app\models\User
	private ?User $_user = null;
	
	// @var NewsletterSubscriber $_subscriber
	private ?NewsletterSubscriber $_subscriber = null;
	
	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->subscription = $this->_user->subscription;
		
		parent::__construct($config);
	}
	
	public function rules()
	{
		return [
			['subscription', 'integer'],
			// Subscription: Inactive(9), Active(10)
			['subscription', 'in', 'range' => [9, 10]],
		];
	}
	
	public function process(): bool
	{
		try
		{
			$model = new NewsletterSubscriber();
			
			// upsertSubscriber(string $email, int $status, ?int $userId = null): bool
			$subscriber = $model->upsertSubscriber(
				$this->_user->email,
				$this->_user->subscription,
				$this->_user->id
			);
			if (!$subscriber)
			{
				throw new YiiBaseException('Failed to update subscription data to the database.');
			}
		
			// Set account Subscription
			$this->_user->subscription = ($this->subscription == 10) ? 9 : 10;
			
			// Use 'false' to skip validation as model is already validated.
			if (!$this->_user->save(false, ['subscription']))
			{
				throw new YiiDbException("Failed to save user data to the database.");
			}
			
			return true;
		}
		catch (\Throwable $e)
		{
			// Use the ExceptionLogger to handle and log the exception.
			ExceptionLogger::log($e, 'account_newsletter_form_error_');
		}
		
		return false;
	}
}

```
account controller:

```
class AccountController extends SeoController
{
	public function actionSettings(): Response|string
	{
		$user = $this->findModel($this->_userId);
		$modelNewsletter = new AccountNewsletterForm($user->id);
		return $this->render('settings', [
			'modelNewsletter' => $modelNewsletter,
		]);
	}
	
	public function actionNewsletter(): 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 newsletter subscription has been successfully updated.</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']);
	}
```

and the view

```
<div class="row mb-1 align-items-center">

<div class="col-sm-6">
<div class="m-2 p-2">
<?php
//$statusText = ($modelNewsletter->subscription == User::SUBSCRIPTION_ACTIVE) 
$statusText = ($modelNewsletter->subscription == 10) ? \Yii::t('app', 'subscribed') : \Yii::t('app', 'unsubscribed');
?>
<p class="subscription-status">
You are currently <b><?= Html::encode($statusText); ?></b> from our newsletter.
</p>
</div><!-- .m-2 p-2 -->
</div><!-- .col-sm-6 -->

<div class="col-sm-6">
<?php
$form = ActiveForm::begin([
	'id' => 'account-newsletter',
	'action' => ['account/newsletter'],
	'method' => 'post',
]);
?>
<div class="row mb-2">

<div class="text-left col-12 col-md-auto">
<?php
//$buttonText = ($modelNewsletter->subscription == User::SUBSCRIPTION_ACTIVE) 
$buttonText = ($modelNewsletter->subscription == 10) ? \Yii::t('app', 'subscribe') : \Yii::t('app', 'unsubscribe');
echo Html::submitButton($buttonText, [
	'class' => 'btn btn-primary square w-100 w-md-auto',
	'name' => 'subscribe-button',
]); ?>
</div><!-- .text-left .col-12 .col-md-auto -->

</div><!-- .row .mb-2 -->
<?php ActiveForm::end(); ?>
</div><!-- .col-sm-6 -->

</div><!-- .row .mb-2 .align-items-center -->
```

but its not working correctly and not sure why.