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've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

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

Getting fields from DataObject with getCMSFields()?


Go to End


6 Posts   11936 Views

Avatar
el.atomo

Community Member, 5 Posts

7 February 2010 at 7:50am

Edited: 07/02/2010 7:55am

Hi!

I've a 1to1 relationship between a Page class and a DataObject:

class Member extends DataObject {
	static $db = array(
		'FirstName' => 'Text',
		...
	)

}

class MemberFounderPage extends Page {
	static $has_one = array(
		'MyMember' => 'Member'
	);
	static $db = array(
		'MemberSince' => 'Date',
		...
	);
	...
}

And I want to push the Member fields into the MemberFounderPage getCMSFields() method, but I'm having trouble with it. I tried to define a getCMSFields() method into the DataObject, and calling it from the MemberFounderPage one:

class MemberFounderPage extends Page {
	...
	function getCMSFields() {
		$fields = parent::getCMSFields();
		$fields->addFieldsToTab("Root.Content.Main", $this->MyMember()->getCMSFields());
		...
		return $fields;
	}
        ...
}

The fields appear on the tab, but they're not saved when saving.

Any hint would be appreciated.

Thanks

Avatar
SSadmin

Community Member, 90 Posts

11 February 2010 at 3:20pm

think u may missing the reverse relationship
in your Member class
class Member extends DataObject {
static $db = array(
'FirstName' => 'Text',
...
)
static $has_one=array(
'ParentMemberFounderPage'=>'MemberFounderPage'
);
}

define the 1-1 relationship you may do the relationship mapping twice.

give it a try.

Avatar
dhensby

Community Member, 253 Posts

11 February 2010 at 3:34pm

Simple answer:

Member::getCMSFields();

if that method even exists in Member

Avatar
el.atomo

Community Member, 5 Posts

12 February 2010 at 2:37pm

Edited: 13/02/2010 1:55am

Thanks for your replies.

SSadmin, I added the $has_one reverse relationship in the Member class, but I'm afraid it has nothing to do with my problem (saving the Member DataObject while editing the Founder Page).

Pigeon, I also tried to use the Member::getCMSFields(), and the fields appear but the form still doesn't save them.

I've gotten some hints by irc, and it seems that the only way to save the dataobject is doing it explicitly inside one onAfterWrite() method.

class MemberFounderPage extendes Page {
	...
	function onAfterWrite() {
		if ($this->MyMemberID == 0) {
			$m = new Member();
			$m->MemberSince = $this->MemberSince;
			...
			$m->write();
		}
		...
		parent::onAfterWrite();
}

Now it almost works, but each time I save the MemberFounderPage form it creates *two* new records in the Member table, one with the values = NULL and the other one with the correct data. Why?

Also, the MyMemberID attribute is not saved in the MemberFounder Table. How could I achieve this?

This is the whole base code:

class Member extends DataObject {
   static $db = array(
   		'FirstName' => 'Text',
   		'LastName' => 'Text
   );

   function getCMSFields() {
   		$fields = new Fieldset();
   		$fields->push( new TextField('FirstName', 'First name') );
   		$fields->push( new TextField('LastName', 'Last name') );
		
   		return $fields;
	 }
}

class MemberFounderPage extends Page {
   static $has_one = array(
   		'MyMember' => 'Member'
   );
   
   static $db = array(
   		'MemberSince' => 'Date'
   );
   
   
   function getCMSFields() {
   		$fields = parent::getCMSFields();
   		$fields->addFieldsToTab("Root.Content.Main", $this->MyMember()->getCMSFields());
   		$fields->addFieldToTab("Root.Content.Main", new CalendarDateField('MemberSince') );
      
   		return $fields;
   }
   
   //onAfterWrite() / onBeforeWrite() code?
}

Thanks a lot

Avatar
el.atomo

Community Member, 5 Posts

13 February 2010 at 8:40am

Edited: 13/02/2010 8:46am

Finally I found a solution to the save/create problem.

The code isn't shiny, and I'm sure there is a better way to achieve this. Any suggestion is appreciated.

class Member extends DataObject {
	static $db = array(
		'FirstName' => 'Text',
		'LastName' => 'Text
	);

	function getCMSFields() {
		$fields = new Fieldset();
		$fields->push( new TextField('FirstName', 'First name', $this->FirstName) );
		$fields->push( new TextField('LastName', 'Last name', $this->LastName) );
      
		return $fields;
	}
}

class MemberFounderPage extends Page {
	static $has_one = array(
		'MyMember' => 'Member'
	);

	static $db = array(
		'MemberSince' => 'Date'
	);

	function getCMSFields() {
		$fields = parent::getCMSFields();
		$fields->addFieldsToTab("Root.Content.Main", $this->MyMember()->getCMSFields());
		$fields->addFieldToTab("Root.Content.Main", new CalendarDateField('MemberSince') );

		return $fields;
	}

	function onBeforeWrite() {
		parent::onBeforeWrite();

		if ($this->MyMemberID) {
			// update sequence
			$mf = DataObject::get_by_id('Member', $this->MyMemberID);
			if ($mf) {
				$mf->FirstName = $this->FirstName;
				$mf->LastName = $this->LastName;
				$mf->write(); // writes row to database
			}
		}
		else {
			// create sequence
			$mf = new Member();
			$mf->FirstName = $this->FirstName; // sets property on object
			$mf->LastName = $this->LastName;
			$mf->write();
			$this->MyMemberID = $mf->ID;
			$this->write();
		}
	}
	
	function onBeforeDelete() {
		$this->MyMember()->delete();
		parent::onBeforeDelete();
	}
}

Avatar
Scheichi

Community Member, 1 Post

6 April 2011 at 8:18pm

Pretty nice solution, el.atomo! Worked awesome for me... thanks for that