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"
    );
}
zanderwar
  • 3,440
  • 3
  • 28
  • 46
  • 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" – Olli Tyynelä Aug 29 '16 at 06:59
  • 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. – zanderwar Aug 29 '16 at 07:06
  • 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. – Olli Tyynelä Aug 29 '16 at 07:37
  • 2
    @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 choosen – Barry Aug 29 '16 at 07:44

1 Answers1

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.

Barry
  • 3,303
  • 7
  • 23
  • 42
  • Thanks @Barry see current bounty if you would like to elaborate on SiteConfig in this context to cover all bases for future reference – zanderwar Aug 29 '16 at 00:38
  • 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. – jlilja Aug 29 '16 at 07:26
  • 1
    @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. – Barry Aug 29 '16 at 07:43
  • @barry: why not use `default_records` config var directl instead of overwriting the requireDefaultRecords() method? See https://github.com/silverstripe/silverstripe-framework/blob/3.4/model/DataObject.php#L3498 – wmk Aug 29 '16 at 08:24
  • @wmk I've added this also, I guess I was trying to give fewer more concise answers than an answer with every possible method – Barry Aug 30 '16 at 07:21