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

[SOLVED] Get values of new object before write


Go to End


7 Posts   8325 Views

Avatar
Hamish

Community Member, 712 Posts

27 May 2009 at 11:30am

Edited: 28/05/2009 10:48am

Hi all,
<br >
<br >Having a little trouble - how do you access the values of a new dataobject before it is written to the database (ie, in onBeforeWrite or Validate)? Note that I mean the first time the object is created, not when it is updated with the rest of the field values.
<br >
<br >During object creation the $changed array seems to be empty and the value of the property is blank. How do you validate a field value before the new object is created (rather than before the new object is updated)? Do you have to check it on update and delete the empty object if it does not validate??
<br >

Avatar
Capt. Morgan

Community Member, 30 Posts

27 May 2009 at 9:18pm

I'm not sure I understand you, but I'll share how I do my validation from Model Admin and hope it helps. I use the getCMSValidator() method to set my own Validatios that in my case is an extended RequiredFields class. Here is don't have the DataObject yet but just a $data array.

Maybe I misunderstod something in your question, but why can't you just access values by $this from onBeforeWrite()?

Avatar
Willr

Forum Moderator, 5523 Posts

27 May 2009 at 10:29pm

Well if you have the object then you have the properties of that object even before its written to the DB. For example this should work fine

$member = new Member();
$member->Name = "Bob";
...
Debug::show($member->Name) // Bob
...
$member->write();

Avatar
Hamish

Community Member, 712 Posts

28 May 2009 at 9:41am

Some more info. This is for dataobjects created by ModelAdmin. I'm using latest trunk (rev 77855). For example:

class TestObject extends DataObject {

	static $db = array('Name' => 'Varchar(30)');

	public function onBeforeWrite() {
		if($this->ID) {
			Debug::message("updating existing object");
		} else {
			Debug::message("creating new object");
		}
		Debug::message("The value of Name is '{$this->Name}'");
		parent::onBeforeWrite();
	}

}

The result of saving a new DataObject with the name "Test" is:

Debug (line 10 of TestObject.php): creating new object

Debug (line 12 of TestObject.php): The value of Name is ''

Debug (line 8 of TestObject.php): updating existing object

Debug (line 12 of TestObject.php): The value of Name is 'test'

I want to use onBeforeWrite (or validate - but it has the same problem) to perform a number of operations before the first object is written.

Avatar
Hamish

Community Member, 712 Posts

28 May 2009 at 9:52am

@Capt. Morgan

Ah, maybe that is the correct method. Will try that.

Avatar
Hamish

Community Member, 712 Posts

28 May 2009 at 10:41am

Well, this is annoying. I created a validator like so:

class TestObject_Validator extends RequiredFields {

	protected $customRequired = array('Name');

	/**
	 * Constructor
	 */
	public function __construct() {
		$required = func_get_args();
		if(isset($required[0]) && is_array($required[0])) {
			$required = $required[0];
		}
		$required = array_merge($required, $this->customRequired);

		parent::__construct($required);
	}
	
	function php($data) {
		Debug::message("Validating data: " . print_r($data, true));
		$valid = parent::php($data);
		Debug::message("Returning false, just to check");
		return false;
	}
}

So, php($data) returns false so it should always fail, but ModelAdmin cheerfully prints the $data array and saves the object!

Response:

Debug (line 40 of TestObject.php):  Validating data: Array
(
[Name] => test 10
)

Debug (line 42 of TestObject.php): Returning false, just to check

Debug (line 10 of TestObject.php): creating new object

Debug (line 12 of TestObject.php): The value of Name is ''

Debug (line 8 of TestObject.php): updating existing object

Debug (line 12 of TestObject.php): The value of Name is 'test 10'

GAH!

Avatar
Hamish

Community Member, 712 Posts

28 May 2009 at 10:47am

Ah ha, so php() has to return false AND add a validation error of some kind:

	function php($data) {
		Debug::message("Validating data: " . print_r($data, true));
		$valid = parent::php($data);
		$this->validationError("Name", "Can't use this name");
		Debug::message("Returning false, just to check");
		return false;
	}