Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

DataObjectManager Module /

Discuss the DataObjectManager module, and the related ImageGallery module.

Moderators: martimiz, UncleCheese, Sean, Ed, biapar, Willr, Ingo, swaiba

New Feature: Intelligent Constructor

Go to End

3 Posts   2130 Views


Forum Moderator, 4102 Posts

11 September 2009 at 4:11am

Many times when using a DOM on your page, you're forced to feed the object a lot of information that is repetitive and redundant. The DataObjectManager and all of its children will now make assumptions about the name, source class, headings, and popup fields. In the following example, I have a very simple DataObject with a very simple relation to its page:


class Product extends DataObject
  static $db = array (
    'Title' => 'Varchar(50)',
    'Description' => 'Text',
    'Price' => 'Decimal',
    'OutOfStock' => 'Boolean'
  static $has_one = array (
    'StorePage' => 'StorePage',
    'ProductImage' => 'Image'
  function getCMSFields()
    return new FieldSet(
      new TextField('Title'),
      new TextareaField('Description'),
      new NumericField('Price'),
      new CheckboxField('OutOfStock','This product is out of stock'),
      new ImageField('ProductImage')


class StorePage extends Page
	static $has_many = array (
	 'Products' => 'Product'
	public function getCMSFields()
		$fields = parent::getCMSFields();
    $fields->addFieldToTab("Root.Content.Products", new DataObjectManager($this));		
		return $fields;

class StorePage_Controller extends Page_Controller

Notice that we have greatly reduced the amount of data we need to feed the DataObjectManager function. Even though we have only passed the controller ($this), it still produces the following result:

Without the intelligent constructor, the code would look like this:

new DataObjectManager(
'Title' => 'Title',
'Description' => 'Description',
'Price' => 'Price',
'OutOfStock' => 'Out Of Stock'

If we want to customize the table headings, we can define in the DataObject:

  static $summary_fields = array (
    'Title' => 'Title',
    'Description' => 'Description'

This produces the following:

How it works

It's not rocket science. :)

- If the name AND source class are left undefined, it will take the first has_many relationship off your controller. In this case, my controller $has_many Products, so it uses that. Right now, relation DOMs will not be able to use intelligent constructors.

- If the headings are left undefined, it loops through your $db array, and formats your fields with a friendly string. (OutOfStock becomes Out Of Stock).

- If the popup fields are left undefined, it uses getCMSFields(). This has always been true with DOM and CTF alike. Very handy.

That's it! For more complex pages, you'll obviously still have to use the full constructor, but if you're like me, you get into a lot of situations where feeding the DOM a bunch of data it should be able to figure out on its own is a bit tedious.



Community Member, 904 Posts

23 September 2009 at 12:30am

Nice feature UncleCheese. Reduces setup time and avoids common mistakes.
When a DataObject has been set to sortable, the "Sort Order" Column also shows up in the automatically generated table headers. I would probably prevent that from happening.. apart from this, another sweet new feature! Thanks.


Forum Moderator, 4102 Posts

23 September 2009 at 1:00am

Great catch. Thanks, Banal.