views:

683

answers:

1

I want to use CakePHP's core validation for lists in my model:

var $validate = array(
  'selectBox' => array(
   'allowedChoice' => array(
    'rule' => array('inList', $listToCheck),
    'message' => 'Enter something in listToCheck.'
   )
  )
);

However, the $listToCheck array is the same array that's used in the view, to populate a selectbox. Where do I put this function?

public function getList() {
    return array('hi'=>'Hello','bi'=>'Goodbye','si'=>'Salutations');
}

Already in my controller, in one of the actions I'm setting it for the view, like:

public function actionForForm() {
 $options = $this->getList();
 $this->set('options', $options);
}

So, I don't want to have to copy the getList() function...where can I put it so the Model can call it to populate its $listToCheck array?

Thanks for your help.

+2  A: 

Considering that it's data, you should store the list of valid choices in the model.

class MyModel extends AppModel {

    var $fieldAbcChoices = array('a' => 'The A', 'b' => 'The B', 'c' => 'The C');

}

You can get that variable in the Controller simply like this:

$this->set('fieldAbcs', $this->MyModel->fieldAbcChoices);

Unfortunately you can't simply use that variable in the rule declaration for the inList rule, since rules are declared as instance variables and those can only be initialized statically (no variables allowed). The best way around that is to set the variable in the Constructor:

var $validate = array(
    'fieldAbc' => array(
        'allowedChoice' => array(
            'rule' => array('inList', array()),
            'message' => 'Enter something in listToCheck.'
        )
    )
);

function __construct($id = false, $table = null, $ds = null) {
    parent::__construct($id, $table, $ds);

    $this->validate['fieldAbc']['allowedChoice']['rule'][1] = array_keys($this->fieldAbcChoices);
}

If you're not comfortable overriding the Constructor, you could also do this in a beforeValidate() callback.

Also note that you shouldn't name your field 'selectBox'. :)

deceze
Thanks for the response. But what happens when I want to use the `__()` function on the fieldAbc values?
Jasie
Then create the whole array in the constructor, or `array_walk` over it and apply the function on `message` fields. `$this->choices = array('a' => __('The A', true), …);`
deceze
Perfect. Thanks for your help!
Jasie