passing value from Yii CController class to CForm (Form Builder) config array

1.1k Views Asked by At

I'm new to Yii, and I'm trying to do my initial project the "right" way. I've created a CFormModel class that needs three fields to query for some data, a CForm config to construct the form, and a CController to tie it together (all given below).

The data request needs an account, and this can come from a couple of different places. I think retrieving it should be in the controller. However, I don't know how to get it into the form's hidden "account" field from the controller, so that it makes it to the arguments assigned to the CFormModel after submission. More generally, I know how to pass from CController to view script, but not to CForm. Is the registry (Yii::app()->params[]) my best bet?

I suppose I can just leave it out of the form (and required fields) and wait to populate it in the submit action (actionSummaries). Does that break the intention of CForm? Is there a best practice? Even taking this solution, can someone address the first issue, in case it comes up again?

Any other, gentle critique is welcome.

models/SummariesForm.php

class SummariesForm extends CFormModel
{
    public $account;
    public $userToken;
    public $year;

    public function rules () {...}

    public function fetchSummary () {...}

    static public function getYearOptions () {...}
}

views/account/select.php

<?php
$this->pageTitle=Yii::app()->name;
?>

<div class="form">
    <?php echo $form->render(); ?>
</div>

controllers/AccountController.php

class AccountController extends CController
{
    public $layout = 'extranet';

    public function actionSelect ()
    {
        $model = new SummariesForm();

        // retrieve account
        require_once 'AccountCookie.php';

        /*
         *
         * Here, I insert the account directly into the
         * model used to build the form, but $model isn't
         * available to selectForm.php. So, it doesn't
         * become part of the form, and this $model doesn't
         * persist to actionSummaries().
         * 
         */
        $model->account = AccountCookie::decrypt();
        if ($model->account === false) {
            throw new Exception('Unable to retrieve account.');
        }

        $form = new CForm('application.views.account.selectForm', $model);
        $this->render('select', array(
            'form'    => $form,
            'account' => $model->account,
        ));
    }

    public function actionSummaries ()
    {
        $model = new SummariesForm();
        if (isset($_POST['SummariesForm'])) {
            $model->attributes = $_POST['SummariesForm'];
            /*
             *
             * Should I just omit "account" from the form altogether
             * and fetch it here? Does that break the "model"?
             * 
             */
                if ($model->validate() === true) {
                try {
                    $summaries = $model->fetchSummary();
                } catch (Exception $e) {
                    ...
                    CApplication::end();
                }

                if (count($summaries) === 0) {
                    $this->render('nodata');
                    CApplication::end();
                }

                $this->render('summaries', array('model' => $model, 'summaries' => $summaries));
            } else {
                throw new Exception('Invalid year.');
            }
        }
    }

}

views/account/selectForm.php

<?php
return array(
    'title' => 'Select year',
    'action' => Yii::app()->createUrl('Account/Summaries'),
    'method' => 'post',

    'elements' => array(
        'account' => array(
            'type'  => 'hidden',
            'value' => $account,
        ),
        'userToken' => array(
            'type'  => 'hidden',
            'value' => /* get token */,
        ),
        'year' => array(
            'type'  => 'dropdownlist',
            'items' => SummariesForm::getYearOptions(),
        ),
    ),

    'buttons' => array(
        'view' => array(
            'type'  => 'submit',
            'label' => 'View summaries',
        ),
    ),
);
1

There are 1 best solutions below

2
On

The answer is NO to do what you asked. You can see $form variable which acted almost like array when it was passed from controller to view. The solution is you add more property $account into selectForm model and treat it like other elements. I don't think leaving the new field outside the form will be properly way if you want to submit its value also.

Edited: enter image description here