SilverStripe 3.4: How to add default records to db from model
Asked Answered
H

1

6

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"
    );
}
Him answered 25/8, 2016 at 6:45 Comment(4)
I think you should split these in to two different questions as @barry ´s answer is correct for how you presented the question. But couple of points on the dataextension: self::get what do you expect that to return?. Or are you extending SiteConfig actually with that?. If you are then you are trying to create mupltiple site configs with that for loop. What you should do is to write the data to the CURRENT site config at hand. Eg. $this->password = "yay"Solder
I thought the same however the issue still revolves around the injection of default values. So rather than repeating myself just updated this question. The relevance goes hand-in-hand. Should probably switch out self for static tho just don't like the idea of referencing the class name within the class itself.Him
self:: is not the class you are extending AFAIK: on that you should you should use SiteConfig::get as it doen't know what data object you want to filter correctly. Saddly can't confirm this at the moment. And you originally were creating a EAV table to some extend, now you should be writing data to the current/newly created SiteConfig, not creating new siteconfigs. Anyways. Lets see does @Barry extend the answer.Solder
@FinBoWa I've decided to extend as per my comment below... both methods work on both objects so it's relevant which ever direction is choosenWainscoting
W
6

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)

The above function isn't needed if all the values are static, instead it will read them just from this array (again within DataObject)

public static $defaults = array(
    'Option1'  => 'Value1',
    'Option2'  => 'Value2'
);

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.

Wainscoting answered 25/8, 2016 at 7:11 Comment(5)
Thanks @Wainscoting see current bounty if you would like to elaborate on SiteConfig in this context to cover all bases for future referenceHim
This answers the original question. And @Zanderwar's question is still about adding default records, not about using SiteConfig ;) Therefore a new question should be added.Uhf
@koodimyyra I'd normally agree, but I should have place another line as I've now done... because both methods work for as they are both DatObjects... and in the context I'm recommending it's worth adding both methods.Wainscoting
@barry: why not use default_records config var directl instead of overwriting the requireDefaultRecords() method? See github.com/silverstripe/silverstripe-framework/blob/3.4/model/…Galactic
@Galactic I've added this also, I guess I was trying to give fewer more concise answers than an answer with every possible methodWainscoting

© 2022 - 2024 — McMap. All rights reserved.