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 >
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.
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()?
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();
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.
@Capt. Morgan
Ah, maybe that is the correct method. Will try that.
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!
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;
}