this is the controller for message view:

    public function actionView(int $id): Response|string
    {
            $model = $this->findModel($id);
            $replyForm = new ReplyForm($model->id);
            //$replyForm = new ReplyForm($model);// Dependency injection.
            $request = \Yii::$app->request;
            if (($request->isPost) && ($replyForm->load($request->post()))) {
                    
                    // Check that Form status is not STATUS_REPLIED, this status should not be manually set via a form.
                    $inputStatus = (int)$replyForm->status;
                    if ($inputStatus !== Message::STATUS_REPLIED) {
                            
                            // Check that current model status is not STATUS_REPLIED and a reply hasn't been set.
                            if (($model->status !== Message::STATUS_REPLIED) && (ValueHelper::isSetAndNull($model->replied))) {
                            
                                    // Determine if a reply has been provided via the form.
                                    $getReply = ValueHelper::isSetNotNull($replyForm->reply);
                                    
                                    // Check if the status has changed from the original model status.
                                    $getStatus = $replyForm->status !== $model->status;
                                    
                                    // Determine scenario based on form changes.
                                    if ($getReply && $getStatus) {
                                    
                                            $replyForm->scenario = 'both';
                                    }
                                    elseif ($getReply) {
                                    
                                            $replyForm->scenario = 'replyOnly';
                                    }
                                    elseif ($getStatus) {
                                    
                                            $replyForm->scenario = 'statusOnly';
                                    }
                            }
                            // Only status change is possible if replied is set.
                            else {
                                    $replyForm->scenario = 'statusOnly';
                            }
                    }
                    
                    // Use the selected scenario to validate form and process.
                    if ($replyForm->validate()) {
                    
                            // Double-check that STATUS_REPLIED is not being saved.
                            if ($inputStatus !== Message::STATUS_REPLIED) {
                                    
                                    if ($replyForm->process()) {
                                            
                                            $this->setScenarioSuccessFlash($replyForm->scenario, $model);
                                            
                                            return $this->redirect(['index']);
                                    }
                                    else {
                                            // Note: Error logging is handled within form Model(s) and user-facing error messages wthin the controller.
                                            $msg = \Yii::t('app', 'There was an error processing your request. Please try again.');
                                            \Yii::$app->session->setFlash('error', $msg);
                                    }
                            }
                            // If trying to save $status as STATUS_REPLIED, give error.
                            else {
                                    $msg = \Yii::t('app', 'Cannot save status to replied.');
                                    \Yii::$app->session->setFlash('error', $msg);
                            }
                    }
                    else {
                            // Validation failed.
                            $msg = \Yii::t('app', 'There was a validation error. Please check your input.');
                            \Yii::$app->session->setFlash('error', $msg);
                    }
            }
            
            // First time viewing Message, change status to Read.
            if (($request->isGet) && ($model->status === Message::STATUS_UNREAD)) {
            
                    $model->addStatus(Message::STATUS_READ);
                    $model->save(false);
            }
            
            // Fetch replies for the message.
            $replies = $model->getReplies()->all();
            
            return $this->render('view', [
                    'model' => $model,
                    'replyForm' => $replyForm,
                    'replies' => $replies,
            ]);
    }
    
    private function setScenarioSuccessFlash(string $scenario, $model): void
    {
            switch ($scenario) {
                    case 'statusOnly' :
                            $msg = \Yii::t('app', 'The status for {to} has been updated.', ['to' => $model->email]);
                            break;
                    case 'replyOnly' :
                    case 'both' :
                    default :
                            $msg = \Yii::t('app', 'Your reply to {to} has been sent.', ['to' => $model->email]);
                            break;
            }
            
            \Yii::$app->session->setFlash('success', $msg);
    }

}

This is my orignal message view file code:
title) . ' (ID: ' . Html::encode($model->id) . ')'; ?>
status; // Define available options $statusOptions = [ Message::STATUS_UNREAD => 'Unread', Message::STATUS_READ => 'Read', Message::STATUS_IMPORTANT => 'Important', Message::STATUS_SPAM => 'Spam', ];

// Include STATUS_REPLIED in options only if it's the current status.
if ($currentStatus === Message::STATUS_REPLIED) {
$statusOptions[Message::STATUS_REPLIED] = 'Replied';
}

echo $form->field($replyForm, 'status')->dropDownList($statusOptions, [
'options' => [$currentStatus => ['Selected' => true]],
'prompt' => \Yii::t('app', 'Select a status...'),
])->hint(\Yii::t('app', 'required'));
?>
title); ?>*/ ?>
asDatetime($model->created_at, 'medium'); ?>
email); ?>
created_ip) ? $model->created_ip : '(not set)'; ?>
subject); ?>
body); ?>
replied) && $model->status !== Message::STATUS_REPLIED) : ?>
field($replyForm, 'reply')->textarea(['rows' => 6])->label('Send a reply:'); ?>
asDatetime($model->repliedTime, 'medium'); ?>
replied); ?>

I need to change it to work with the following changes witihn my message model:

class Message extends ActiveRecord
{
const STATUS_UNREAD = 1;// 0b00001
const STATUS_READ = 2;// 0b00010
const STATUS_IMPORTANT = 4;// 0b00100
const STATUS_RESOLVED = 8;// 0b01000
const STATUS_SPAM = 16;// 0b10000
const STATUS_ARCHIVED = 32;// 0b100000
const STATUS_FLAGGED = 64;// 0b110000

    public function setStatusFromCheckboxes($checkboxes): void
    {
            $this->status = 0;
            foreach ($checkboxes as $value) {
                    
                    $this->addStatus((int)$value);
            }
    }
    
    public function addStatus($status): void
    {
            $this->status |= $status;
    }
    
    public function removeStatus($status): void
    {
            $this->status &= ~$status;
    }
    
    public function hasStatus($status): bool
    {
            
            return ($this->status & $status) === $status;
    }
    
    public function getReplies(): MessageQuery
    {
            return $this->hasMany(self::class, ['parent_id' => 'id']);
    }

}

Was thinking of adding something like the following code into the view so i could see the list of replies:
title) . ' (ID: ' . Html::encode($model->id) . ')'; ?>

        <!-- Status and existing message details (your existing code) -->

        <!-- Existing reply form logic here... -->

    </div><!-- .form-container -->

    <!-- Displaying Replies -->
    <div class="replies-container mt-4">
        <h6><?= \Yii::t('app', 'Replies:') ?></h6>
        <?php if (empty($replies)) : ?>
            <p><?= \Yii::t('app', 'No replies yet.') ?></p>
        <?php else : ?>
            <ul class="list-unstyled">
                <?php foreach ($replies as $reply) : ?>
                    <li class="reply-item">
                        <div class="card">
                            <div class="card-header">
                                <h6 class="font-italic"><?= \Yii::t('app', 'Replied on: ') . $formatter->asDatetime($reply->created_at, 'medium'); ?></h6>
                            </div>
                            <div class="card-body">
                                <?= Html::encode($reply->body); ?>
                            </div>
                        </div>
                    </li>
                <?php endforeach; ?>
            </ul>
        <?php endif; ?>
    </div><!-- .replies-container -->
</div><!-- .card-body -->

To adapt your message view file to accommodate the changes in your Message model, particularly regarding the handling of statuses as bitwise values, you'll want to make several updates. Your goal is to ensure that the status checkboxes are displayed correctly and that the existing replies are listed in an organized manner.

Here’s how you can incorporate the changes you outlined:
Revised Message View File

<div class="card admin-card">
    <div class="card-header admin-card-header">
        <h5 class="mb-0"><?= Html::encode($this->title) . ' (ID: ' . Html::encode($model->id) . ')'; ?></h5>
    </div>
    <div class="card-body admin-card-body">
        <div class="form-container">

            <div class="reply-form-status">
                <?php
                // Prepare status checkboxes for the form.
                $availableStatuses = [
                    Message::STATUS_UNREAD => 'Unread',
                    Message::STATUS_READ => 'Read',
                    Message::STATUS_IMPORTANT => 'Important',
                    Message::STATUS_SPAM => 'Spam',
                    Message::STATUS_RESOLVED => 'Resolved',
                    Message::STATUS_ARCHIVED => 'Archived',
                    Message::STATUS_FLAGGED => 'Flagged',
                ];

                // Collect currently set statuses.
                $currentStatuses = [];
                foreach ($availableStatuses as $value => $label) {
                    if ($model->hasStatus($value)) {
                        $currentStatuses[] = $value;
                    }
                }

                // Display checkboxes for status.
                echo '<div>';
                foreach ($availableStatuses as $value => $label) {
                    echo $form->field($replyForm, 'checkboxes[]')->checkbox(['value' => $value, 'checked' => in_array($value, $currentStatuses)])->label($label);
                }
                echo '</div>';
                ?>
            </div><!-- .reply-form-status -->

            <div class="card">
                <div class="card-header">
                    <h6 class="font-italic"><?= \Yii::t('app', 'Sent on: ') . $formatter->asDatetime($model->created_at, 'medium'); ?></h6>
                    <h6><?= \Yii::t('app', 'Sent by: ') . Html::encode($model->email); ?></h6>
                    <h6><?= \Yii::t('app', 'IP: ') . ($model->created_ip ? $model->created_ip : '(not set)'); ?></h6>
                    <h6><?= \Yii::t('app', 'Subject: ') . Html::encode($model->subject); ?></h6>
                </div>

                <div class="card-body m-3 p-0">
                    <?= Html::encode($model->body); ?>
                </div>
            </div><!-- .card -->

            <?php if (ValueHelper::isSetAndNull($model->replied) && !$model->hasStatus(Message::STATUS_REPLIED)) : ?>
                <div class="reply-form-reply mt-3 ms-3">
                    <?= $form->field($replyForm, 'reply')->textarea(['rows' => 6])->label('Send a reply:'); ?>
                </div><!-- .reply-form-reply -->
            <?php else : ?>
                <div class="reply-form-reply mt-3 ms-3">
                    <div class="card">
                        <div class="card-header">
                            <h6 class="font-italic"><?= \Yii::t('app', 'Replied on: ') . $formatter->asDatetime($model->repliedTime, 'medium'); ?></h6>
                        </div>
                        <div class="card-body m-3 p-0">
                            <?= Html::encode($model->replied); ?>
                        </div>
                    </div>
                </div><!-- .reply-form-reply -->
            <?php endif; ?>
        </div><!-- .form-container -->

        <!-- Displaying Replies -->
        <div class="replies-container mt-4">
            <h6><?= \Yii::t('app', 'Replies:') ?></h6>
            <?php if (empty($replies)) : ?>
                <p><?= \Yii::t('app', 'No replies yet.') ?></p>
            <?php else : ?>
                <ul class="list-unstyled">
                    <?php foreach ($replies as $reply) : ?>
                        <li class="reply-item">
                            <div class="card">
                                <div class="card-header">
                                    <h6 class="font-italic"><?= \Yii::t('app', 'Replied on: ') . $formatter->asDatetime($reply->created_at, 'medium'); ?></h6>
                                </div>
                                <div class="card-body">
                                    <?= Html::encode($reply->body); ?>
                                </div>
                            </div>
                        </li>
                    <?php endforeach; ?>
                </ul>
            <?php endif; ?>
        </div><!-- .replies-container -->
    </div><!-- .card-body -->
</div><!-- .card -->

Key Changes Explained

    Checkboxes for Statuses:
        In the revised view file, checkboxes are created for each status using the hasStatus method to determine if the message has that status set. This allows for multi-selection of statuses as defined in your Message model.

    Reply Display Logic:
        The existing reply display logic now iterates through the replies associated with the message, correctly showing their timestamps and content.

    Form and Reply Structure:
        The overall structure keeps the form fields and replies section organized, allowing users to easily add new replies while reviewing past interactions.

This revised code provides a dynamic and functional view that incorporates the new Message model's status handling capabilities. Ensure that the controller handles the submitted values from checkboxes correctly by implementing the setStatusFromCheckboxes method during the form processing phase.

is is the replyForm model code:

class ReplyForm extends Model
{
public $status;
public $reply;

    private $_message;
    private $_emailSupport;
    
    //public function __construct(Contact $contact, $config = [])// Dependency injection.
    public function __construct($id, $config = [])
    {
            // @var ParamHelper to class property.
            $this->_emailSupport = ParamHelper::get('email.support');
    
            /**
            * Dependency injection. Passing Contact model into a class through its constructor.
            *
            $this->_message = $message;//*/
            
            /**
            * Assign Model Object class propert to a local variable for improved 
            * readability, convenience, and to prevent accidental modifications to 
            * the class property when performing local operations on the user object.
            */
            $this->_message = Message::findOne($id);
            $message = $this->_message;
            if (!$message) {
            
                    $msg = \Yii::t('app', 'Unable to find Message.');
                    throw new YiiBaseInvalidArgumentException($msg);
            }
            
            parent::__construct($config);
    }
    
    public function rules(): array
    {
            return [
                    // No fields are mandatory due to defaults; validate if they are set
                    [['status', 'reply'], 'safe'],
                    
                    /**
                    * Example of syntax to require attributes per scenario, if needed:
                    */
                    //[['status'], 'required', 'on' => 'statusOnly'],
                    // [['reply'], 'required', 'on' => 'replyOnly'],
                    // [['status', 'reply'], 'required', 'on' => 'both'],
            ];
    }
    
    public function scenarios()
    {
            $scenarios = parent::scenarios();
            $scenarios['replyOnly'] = ['reply'];// Only sends a reply.
            $scenarios['statusOnly'] = ['status'];// Only updates the status.
            $scenarios['both'] = ['status', 'reply'];// Updates both status and reply.
            
            return $scenarios;
    }
    
    public function attributeLabels(): array
    {
            return ['replied' => \Yii::t('app', 'Reply')];
    }
    
    public function process(): bool
    {
            $message = $this->_message;
            $transaction = \Yii::$app->db->beginTransaction();
            try {
                    $scenario = $this->getScenario();
                    $updatedFields = [];// Contact model attubutes.
                    
                    // If Message Model status is not set to 'replied', and form Model 'reply' is not empty.
                    $inputStatus = (int)$message->status;
                    if (($inputStatus !== Message::STATUS_REPLIED) && (!empty($this->reply))) {
                    
                            if (in_array($scenario, ['both'])) {
                                    
                                    $message->status = $message->addStatus($this->status);
                                    $message->replied = $this->reply;
                                    $message->repliedTime = time();// Set it to the current Unix timestamp. 
                                    //$message->repliedTime = date('Y-m-d H:i:s');// If defined as a timestamp '$this->timestamp()'.
                                    $updatedFields = ['status', 'replied', 'repliedTime'];
                            }
                            if (in_array($scenario, ['replyOnly'])) {
                                    
                                    $message->status = $message->addStatus(Message::STATUS_REPLIED);
                                    $message->replied = $this->reply;
                                    $message->repliedTime = time();
                                    //$message->repliedTime = date('Y-m-d H:i:s');
                                    $updatedFields = ['status', 'replied', 'repliedTime'];
                            }
                            if (in_array($scenario, ['statusOnly'])) {
                            
                                    $message->status = $message->addStatus($this->status);
                                    $updatedFields[] = 'status';
                            }
                    }
                    else {
                            $message->status = $message->addStatus($this->status);
                            $updatedFields[] = 'status';
                    }
                    
                    // Save Contact model depending on Scenario.
                    if ($message->save(false, $updatedFields)) {
                            if ((in_array($scenario, ['replyOnly', 'both'])) && (!empty($this->reply))) {
                            
                                    if (!$this->sendEmail($message)) {
                                    
                                            throw new YiiBaseException('Failed to send email.');
                                    }
                            }
                            
                            // 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, 'reply_form_error_');
            }
            
            return false;
    }

}

Your ReplyForm model is well-structured, but I can provide you with some refinements that enhance the integration with the changes in your Message model and clarifications in regards to the submitting statuses as checkboxes.
Key Improvements for ReplyForm:

    Checkbox Handling: You need to ensure that the form can accept an array of statuses when the user submits checkboxes.

    Validation: You may want to make the reply field required only in specific scenarios while still keeping the status field optional based on the scenario.

    Updating Statuses: The method responsible for processing the statuses should be adjusted to accommodate multiple status values from checkboxes.

Updated ReplyForm Code:

Here’s how the ReplyForm model can be updated:

class ReplyForm extends Model
{
    public $checkboxes = []; // Changed from `$status` to `checkboxes`
    public $reply;

    private $_message;
    private $_emailSupport;

    public function __construct($id, $config = [])
    {
        $this->_emailSupport = ParamHelper::get('email.support');
        $this->_message = Message::findOne($id);

        if (!$this->_message) {
            throw new YiiBaseInvalidArgumentException(\Yii::t('app', 'Unable to find Message.'));
        }

        parent::__construct($config);
    }

    public function rules(): array
    {
        return [
            [['checkboxes', 'reply'], 'safe'],
            [['reply'], 'required', 'on' => 'replyOnly'], // Making reply required on the replyOnly scenario
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['replyOnly'] = ['reply'];
        $scenarios['statusOnly'] = ['checkboxes']; // Using checkboxes to update status
        $scenarios['both'] = ['checkboxes', 'reply'];

        return $scenarios;
    }

    public function attributeLabels(): array
    {
        return ['reply' => \Yii::t('app', 'Reply')];
    }

    public function process(): bool
    {
        $message = $this->_message;
        $transaction = \Yii::$app->db->beginTransaction();

        try {
            $scenario = $this->getScenario();
            $updatedFields = [];

            // Process checkboxes for statuses
            $statusInput = $this->checkboxes;
            $message->setStatusFromCheckboxes($statusInput); // Update status based on checkbox inputs

            // Set replied details if applicable
            if (!empty($this->reply)) {
                $message->replied = $this->reply;
                $message->repliedTime = time();
                $updatedFields = array_merge($updatedFields, ['replied', 'repliedTime']);
            }

            // Save updated message fields
            if ($message->save(false, array_merge(['status'], $updatedFields))) {
                if (!empty($this->reply) && in_array($scenario, ['replyOnly', 'both'])) {
                    if (!$this->sendEmail($message)) {
                        throw new YiiBaseException('Failed to send email.');
                    }
                }

                $transaction->commit();
                return true;
            }
        } catch (\Throwable $e) {
            $transaction->rollBack();
            ExceptionLogger::log($e, 'reply_form_error_');
        }

        return false;
    }
}

Key Changes Explained:

    Checkbox Array: Changed the status property to checkboxes, an array that can store multiple selected statuses.

    Validations: The reply field is required during the replyOnly scenario.

    Simplified Scenario Handling: You can now handle the updates of statuses from the checkboxes efficiently in the process method using setStatusFromCheckboxes.

    Transaction Management: This remains the same, ensuring that if there's an error, changes can be rolled back.

Integrating with Your Controller:

Ensure that your controller action takes input from the updated ReplyForm:

if ($request->isPost && $replyForm->load($request->post())) {
    // Handle form submission
    if ($replyForm->validate()) {
        if ($replyForm->process()) {
            // Success logic...
        }
    } // Error handling...
}

Summary

The modifications in the ReplyForm make it flexible to handle the new status management via checkboxes while still allowing for replies. These succinct improvements should streamline function and logic clarity in your application workflow surrounding message replies.

oh i see what you did.. you made the dropdown list a checkboxes.. that isn't what the goal is, Im not sure if bootstrap 5 dropdownlist gives the option for multi select, but if it does... thats what i want.

If you're looking to modify the status selection approach so that a Bootstrap 5 dropdown menu allows for multi-select, you can use a customized dropdown that behaves like a multi-select. Unfortunately, Bootstrap's default dropdown does not support multi-select options directly. However, you can create a custom multi-select dropdown using a few different approaches.
Using Bootstrap 5 with a Custom Multi-Select Dropdown

You can achieve a multi-select behavior using a combination of Bootstrap's dropdown functionality and some custom JavaScript for handling selections. Here's an example setup:

    Bootstrap Dropdown for Multi-Select:

You can use a dropdown along with jQuery or plain JavaScript to manage the selected statuses. Below is an example of how you can create a custom multi-select dropdown using Bootstrap 5.
HTML and JavaScript Code:

Here's how you could implement it in your message view file:

<div class="reply-form-status">
    <div class="dropdown">
        <button class="btn btn-secondary dropdown-toggle" type="button" id="statusDropdown" data-bs-toggle="dropdown" aria-expanded="false">
            Select Status
        </button>
        <ul class="dropdown-menu" aria-labelledby="statusDropdown">
            <?php
            $availableStatuses = [ 
                Message::STATUS_UNREAD => 'Unread',
                Message::STATUS_READ => 'Read',
                Message::STATUS_IMPORTANT => 'Important',
                Message::STATUS_SPAM => 'Spam',
                Message::STATUS_RESOLVED => 'Resolved',
                Message::STATUS_ARCHIVED => 'Archived',
                Message::STATUS_FLAGGED => 'Flagged',
            ];

            foreach ($availableStatuses as $value => $label) {
                echo '<li><a class="dropdown-item status-option" href="#" data-value="'.$value.'">'.$label.'</a></li>';
            }
            ?>
        </ul>
    </div>
    <div id="selectedStatus" class="mt-2">
        <strong>Selected Statuses: </strong><span id="statusText"></span>
    </div>
    <?= $form->field($replyForm, 'checkboxes[]')->hiddenInput(['id' => 'statusInput'])->label(false) ?>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const selectedStatusElement = document.getElementById('statusText');
    const statusInput = document.getElementById('statusInput');
    const statusOptions = [];

    document.querySelectorAll('.status-option').forEach(option => {
        option.addEventListener('click', function(event) {
            event.preventDefault();
            const value = this.getAttribute('data-value');
            if (statusOptions.includes(value)) {
                statusOptions.splice(statusOptions.indexOf(value), 1); // Remove if already selected
                this.classList.remove('active');
            } else {
                statusOptions.push(value); // Add if not selected
                this.classList.add('active');
            }

            // Update the displayed selected statuses
            selectedStatusElement.textContent = statusOptions.join(', ') || 'None';
            // Update the hidden input value
            statusInput.value = statusOptions.join(',');
        });
    });
});
</script>

Explanation of the Code:

    Dropdown Button: This is the Bootstrap button which opens the dropdown menu.

    Dropdown Items: Each status is represented as a dropdown item, and clicking on it will toggle its selection.

    JavaScript Handling: The JavaScript maintains a list of selected statuses. When an item is clicked:
        If it is already in the selection, it is removed.
        If it is not selected, it is added to the selection.
        The selection updates the display text showing the currently selected statuses and populates a hidden input field so that it can be submitted with the form.

    Hidden Input: A hidden input field (statusInput) is used to store the selected statuses. This input is submitted with the rest of the form.

Integrating with the ReplyForm Model

You may need to adjust your ReplyForm model to handle the submitted comma-separated string from the hidden input correctly. Here’s how you can adapt the ReplyForm:

class ReplyForm extends Model
{
    public $checkboxes = []; // Keep it as an array
    public $reply;

    private $_message;
    private $_emailSupport;

    public function __construct($id, $config = [])
    {
        // Constructor as before...
    }

    public function rules(): array
    {
        return [
            [['checkboxes', 'reply'], 'safe'],
            [['reply'], 'required', 'on' => 'replyOnly'],
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['replyOnly'] = ['reply'];
        $scenarios['statusOnly'] = ['checkboxes'];
        $scenarios['both'] = ['checkboxes', 'reply'];

        return $scenarios;
    }

    public function attributeLabels(): array
    {
        return ['reply' => \Yii::t('app', 'Reply')];
    }

    public function setCheckboxes($checkboxesString)
    {
        $this->checkboxes = explode(',', $checkboxesString);
    }

    public function process(): bool
    {
        // Process method as before...
    }
}

Summary

This method gives you a customizable and user-friendly multi-select experience using Bootstrap's dropdowns while ensuring the selected values are appropriately captured in your form submission. Just make sure you include the necessary Bootstrap JS and CSS files in your project to enable dropdown functionality.















So i never asked you to change my code, other then to make the nesscarry corrections so that the message model code,
would work with the view file and replyForm. Code below is what you did:

class ReplyForm extends Model
{
    public $checkboxes = []; // Changed from `$status` to `checkboxes`
    public $reply;

    private $_message;
    private $_emailSupport;

    public function __construct($id, $config = [])
    {
        $this->_emailSupport = ParamHelper::get('email.support');
        $this->_message = Message::findOne($id);

        if (!$this->_message) {
            throw new YiiBaseInvalidArgumentException(\Yii::t('app', 'Unable to find Message.'));
        }

        parent::__construct($config);
    }

    public function rules(): array
    {
        return [
            [['checkboxes', 'reply'], 'safe'],
            [['reply'], 'required', 'on' => 'replyOnly'], // Making reply required on the replyOnly scenario
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['replyOnly'] = ['reply'];
        $scenarios['statusOnly'] = ['checkboxes']; // Using checkboxes to update status
        $scenarios['both'] = ['checkboxes', 'reply'];

        return $scenarios;
    }

    public function attributeLabels(): array
    {
        return ['reply' => \Yii::t('app', 'Reply')];
    }

    public function process(): bool
    {
        $message = $this->_message;
        $transaction = \Yii::$app->db->beginTransaction();

        try {
            $scenario = $this->getScenario();
            $updatedFields = [];

            // Process checkboxes for statuses
            $statusInput = $this->checkboxes;
            $message->setStatusFromCheckboxes($statusInput); // Update status based on checkbox inputs

            // Set replied details if applicable
            if (!empty($this->reply)) {
                $message->replied = $this->reply;
                $message->repliedTime = time();
                $updatedFields = array_merge($updatedFields, ['replied', 'repliedTime']);
            }

            // Save updated message fields
            if ($message->save(false, array_merge(['status'], $updatedFields))) {
                if (!empty($this->reply) && in_array($scenario, ['replyOnly', 'both'])) {
                    if (!$this->sendEmail($message)) {
                        throw new YiiBaseException('Failed to send email.');
                    }
                }

                $transaction->commit();
                return true;
            }
        } catch (\Throwable $e) {
            $transaction->rollBack();
            ExceptionLogger::log($e, 'reply_form_error_');
        }

        return false;
    }
}

I want to know why you removed the following that I had in the original:

			if (($inputStatus !== Message::STATUS_REPLIED) && (!empty($this->reply))) {
			
				if (in_array($scenario, ['both'])) {
					
					$message->status = $message->addStatus($this->status);// Im aware this isn't needed now.
					$message->replied = $this->reply;
					$message->repliedTime = time();// Set it to the current Unix timestamp. 
					//$message->repliedTime = date('Y-m-d H:i:s');// If defined as a timestamp '$this->timestamp()'.
					$updatedFields = ['status', 'replied', 'repliedTime'];
				}
				if (in_array($scenario, ['replyOnly'])) {
					
					$message->status = $message->addStatus(Message::STATUS_REPLIED);/ But! this code is.. the status_replied needs to be set by the code.
					$message->replied = $this->reply;
					$message->repliedTime = time();
					//$message->repliedTime = date('Y-m-d H:i:s');
					$updatedFields = ['status', 'replied', 'repliedTime'];
				}
				if (in_array($scenario, ['statusOnly'])) {
				
					$message->status = $message->addStatus($this->status);
					$updatedFields[] = 'status';
				}
			}
			else {
				$message->status = $message->addStatus($this->status);
				$updatedFields[] = 'status';
			}
			
			// Save Contact model depending on Scenario.
			if ($message->save(false, $updatedFields)) {
				if ((in_array($scenario, ['replyOnly', 'both'])) && (!empty($this->reply))) {
				
					if (!$this->sendEmail($message)) {
					
						throw new YiiBaseException('Failed to send email.');
					}
				}
				
				// If all saves are successful, commit the transaction.
				$transaction->commit();
				
				return true;
			}
			
			
I know the option within the view has:

$availableStatuses = [
	Message::STATUS_UNREAD => 'Unread',
	Message::STATUS_READ => 'Read',
	Message::STATUS_IMPORTANT => 'Important',
	Message::STATUS_SPAM => 'Spam',
	Message::STATUS_RESOLVED => 'Resolved',
	Message::STATUS_ARCHIVED => 'Archived',
	Message::STATUS_FLAGGED => 'Flagged',
];
// Collect currently set statuses.
$currentStatuses = [];
foreach ($availableStatuses as $value => $label) {
	if ($model->hasStatus($value)) {
	
		$currentStatuses[] = $value;
	}
}

// Display checkboxes for status.
echo '<div>';
foreach ($availableStatuses as $value => $label) {
	
	echo $form->field($replyForm, 'checkboxes[]')->checkbox([
		'value' => $value, 'checked' => in_array($value, $currentStatuses)
	])->label($label);
}
echo '</div>';

i decided to use your suggested checkbox code for testing, which is fine. but as you can see the status_replied is only done in the backend.