Zanderwar Zanderwar - 3 months ago 15
PHP Question

SilverStripe 3.4: How to add default records to db from model

Unable to locate in the SilverStripe Documentation how to have a DataObject Model inject a collection of default records on /dev/build

Anybody able to point me in the right direction

This is what I currently have, and obviously I would like to inject pre-configured options into this aptly named Configuration model for my Module.

class Configuration extends DataObject
{
private static $db = array(
'Option' => 'Varchar',
'Value' => 'Varchar'
);

private static $summary_fields = array(
'Option' => 'Option',
'Value' => 'Value',
);
}


Thanks in advance for any direction/pointers.

UPDATE
I was turned onto SiteConfig by @Barry below

However in following his practice, requireDefaultRecords() is not injecting defaults


Note: I have since revisited /dev/build?flush


class RMSConfiguration extends DataExtension
{
private static $db = array(
'username' => 'Varchar',
'password' => 'Varchar',
'agent_id' => 'Varchar(15)',
'client_id' => 'Varchar(15)',
'testMode' => 'Int(1)',
'timezone' => 'Varchar',
'apiUrl' => 'Varchar(255)'
);

public function updateCMSFields(FieldList $fields)
{
$fields->addFieldsToTab(
"Root.RMSConfig",
array(
TextField::create('username', 'RMS Username'),
TextField::create('password', 'RMS Password'),
TextField::create('agent_id', 'RMS Agent ID'),
TextField::create('client_id', 'RMS Client ID'),
TextField::create('apiUrl', 'API Url'),
CheckboxField::create("testMode", 'Toggle Test Mode'),
DropdownField::create("timezone", 'Timezone', static::$timezones)
)
);

}

public function requireDefaultRecords()
{
parent::requireDefaultRecords();

$arrOptions = array(
'timezone' => 'Australia/Sydney',
'apiUrl' => 'https://api.example.com.au/',
'testMode' => 0
);

foreach ($arrOptions as $strOption => $strValue) {
if (!$configuration = self::get()->filter('Option', $strOption)->first()) {
$configuration = self::create(array( 'Option' => $strOption ));
}

$configuration->Value = $strValue;
$configuration->write();
}
}

/**
* List of timezones supported by PHP >=5.3.x
*
* @var array
*/
public static $timezones = array(
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
"Africa/Algiers",
...
...
"Zulu"
);
}

Answer

Using the function requireDefaultRecords in the DataObject - this is called during every dev/build.

Note: First check if the option exists to prevent duplicates as this will be called every time you dev build.

class Configuration extends DataObject {

    private static $db = array(
        'Option' => 'Varchar',
        'Value'  => 'Varchar'
    );

    private static $summary_fields = array(
        'Option' => 'Option',
        'Value'  => 'Value',
    );

    function requireDefaultRecords() {
        parent::requireDefaultRecords();

        $arrOptions = array(
            'Option1' => 'Value1',
            'Option2' => 'Value2',
            'Option3' => 'Value3',
        );

        foreach ($arrOptions as $strOption => $strValue) {
            if (!$configuration = Configuration::get()->filter('Option',$strOption)->first())
                $configuration = Configuration::create(array('Option' => $strOption));

            $configuration->Value = $strValue;
            $configuration->write();
        }
    }
}

One final comment is that there is a module for SiteConfig which is used by SilverStripe, most modules and where I would recommend you put configuration values like this instead.

If you do choose SiteConfig then please see the function populateDefaults and documentation for it's use, this is an example...

/**
 * Sets the Date field to the current date.
 */
public function populateDefaults() {
    $this->Date = date('Y-m-d');
    parent::populateDefaults();
}

(if the above is used in an extensions it might need $this->owner->Date instead of $this->Date)

This works on any DataObject as well, but as SiteConfig manages one record and this populates that record once upon creation this is much more convenient for to use instead of requireDefaultRecords.