Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
What is best way to extend Orm and Fieldset behavior for custom select options?
  • I am trying to build out an model extension of Orm with some added functionality around fieldset handling when loading a model's fields into the fieldset instance.  I am using _property setting of the 'form' attribute but running into some issues/questions on how to best  extend for doing runtime setting of values.

    I have gotten things to work but unsure what best practice is (or if I missed a hook/override somewhere in docs/examples).  First use case where I am trying to extend is with select options.  I have a model hierarchy as such:

    Player
         Basketball_Player extends Player
         Football_Player extends Player

    For the property 'position' I have it setup as a select field with various dropdown options and b/c Basketball and Football have different sets of positions I set as static properties at the specific classes.., for example, Basketball_Player has:

    protected static $positions = array('PG','C','PF','SF','G');

    In my static _properties array in the main Model_Player class I have the following for 'position':

            'position' => array(
                'data_type' => 'varchar',
                'label' => 'Position',
                'validation' => array('required', 'min_length' => array(1), 'max_length' => array(10)),
                'form' => array('type' => 'select', 'options' => 'positions'),
            ),

    I have extending the package/orm/observer/validation.php class to support a "custom callback" for setting of options at runtime when the 'options' value for 'form' is a string...this is one use case, another is where I will need to call the db to generate the options values.  When 'set_form_fields' is called inside of the Orm\Model class it will eventually hit the validation.php set_fields() call, detect the 'positions' string value for the 'options' attribute and do the following:

                        $options_callback = '_options_'.$settings['form']['options'];
                        $options = is_object($obj) ? $obj->$options_callback() : 
                                                                                   $class::$options_callback();
                        $settings['form']['options'] = $options;

    I tried to mimick what is done earlier in the set_fields() function call where it checks for is_object and calls appropriately instance or static.  Inside my Basketball_Player class I have the function:

        public static function _options_positions()
        {
            return self::$positions;
        }

    Is there a cleaner or more out of box way to create this type of behavior?
  • Are the options really a runtime property?

    It's a lot easier to simply add a _init() method to your model, and have that add the options to the property.
  • In the use case of the positions example above for a players model its not necessary for runtime callback.

    Others scenarios I need to deal with are pulling select options from the database, as well as "dependent options" where one property's options are related to another property's value.  Can _init be leveraged in these scenarios as well where the model would be created and retrieved with the instance?
  • We use the following standard in your applications:

    If the options list is static (i.e. it doesn't change in the course of processing a request), we populate the array in _init(). If the list is dynamic, we use set_form_fields() to populate it when creating the fieldset from the model (it is called when you use add_model() on the fieldset).

    For optimisation, there are some caching mechanisms built in to avoid generating the same options list multiple times.
  • I tried set_form_fields initially and seemed like I was getting experience where my model that is extending Orm had the function called but the fieldset instance was null so I couldnt do standard custom parts in my function, then call parent to take over the rest.

    Is that the case when extending Orm or should that be "out of box" for my custom select options scenarios?
  • The fieldset object is returned after you have called the parent, so you can use that.
  • So then I would take the fieldset object that is returned then grab the select field(s) that were just set in parent::set_form_fields and edit their values?
  • HarroHarro
    Accepted Answer
    Looked at the code again.

    The fieldset is the first parameter of set_form_fields(), and it is always passed. So you should be able to access the fieldset both before and after the model's fields have been added.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion