As the Record Browser access settings are now stored in a database with pre-defined criteria keys this limits the possibility of influencing the records accessed based on other RB recordset contents.
The background - In my case I had to set up a separate RB recordset for record authorizations of another recordset. The admin then adds allowed authorizations in a special custom field for each user.
The EPESI documentation still lists the access callback as the way to define access to RB records but then I found out this feature is not available anymore.
In my case it would have been perfect to use a callback as I need to base the access crits on other recordset values.
So I figured out how to modify the RB code to add such functionality. I will appreciate if you consider adding it as standard in future EPESI versions.
The editing in RB permissions editor and all around testing is pending though.
The concept is that the callback adds (AND) crits to every crit that is defined through the permissions editor. If there is any permission to view the records.
Following code I inserted in Utils_RecordBrowserCommon::get_access function after retrieving crits from the database.
$r = DB::Execute('SELECT * FROM '.$tab.'_access AS acs WHERE action=\'callback\'');
while ($row = $r->FetchRow()) {
$cb_func = unserialize($row['crits']);
if (is_callable($cb_func) && Base_AclCommon::i_am_user()) $callback_crits = call_user_func($cb_func, $tab, $record);
foreach ($callback_crits as $a=>$c) {
$cb_crits[$a] = self::parse_access_crits($c);
}
}
foreach ($cb_crits as $a=>$c) {
if (is_null($crits[$a])) continue;
$crits[$a] = self::merge_crits($crits[$a], $c);
foreach ($crits_raw[$a] as $raw_key=>$raw_value) {
$crits_raw[$a][$raw_key] = $c + $raw_value;
}
}
Then I had to modify Utils_RecordBrowserCommon::check_record_against_crits to accept crits for one field as array (OR crits).
if (is_array($r[$k])) {
if (is_array($v)) {
$result = array_intersect($v, $r[$k]); //MODIFIED PART
}
else $result = in_array($v, $r[$k]);
}
else {
//MODIFIED PART
if (is_array($v)) {
$result = in_array($r[$k], $v);
}
else switch ($operator) {
case '>': $result = ($r[$k] > $v); break;
case '>=': $result = ($r[$k] >= $v); break;
case '<': $result = ($r[$k] < $v); break;
case '<=': $result = ($r[$k] <= $v); break;
case '==': $result = ($r[$k] == $v);
}
}
When installing the recordset the callback definition can be added as follows:
Utils_RecordBrowserCommon::add_access('recordset_name', 'callback', '', 'ModuleCommon::access_callback_function');