Hi,
I'll answer for the second question. RBO is based on RB. I was sick of typing this long Utils_RecordBrowserCommon::do_something('the same string here again', ...) and I've written objective wrapper for this - it's called RBO.
So if you can't find something in your Recordset object, then try to find it in Utils_RecordBrowserCommon static methods.
$rs = new Custom_Contract_Recordset();
$rs->register_processing_callback(array(class, method));
is the same as
Utils_RecordBrowserCommon::register_processing_callback($rs->table_name(), array(class, method));
It's even better to override install method in your Recordset class
class Custom_Contract_Recordset extends RBO_Recordset {
...
public function install() {
$success = parent::install();
if ($success) {
$this->register_processing_callback(array(__CLASS__, 'process_record'));
.. other stuff like caption, favorites, watchdog, etc
}
}
// note 'static' - it's required for processing callbacks
public static function process_record($values, $mode) {
...
}
}
Now your first question.
To implement some form validation, don't use processing callback. Use quickform form rule.
If you use processing callback, then you can return false to break the action. (see this line)
But form will not generate any information why the record has not been added.
In my opinion the best way to achieve this would be to use addFormRule to check for duplicates.
Search epesi source for addFormRule, and you should get how to use it.