The onDeleteRowsForm hook is called from the main list model deleteRows() method, which is called both when you do a list delete (potentially with multiple rows) and also from form controller when you delete from a form view.
In both case, the form PHP plugin's onDeleteRowsForm() method is triggered, with the row data in $data, which is an array of arrays (groups) of objects (rows). So you should always code it assuming that you may get called with multiple rows (deleting from a list will do that). Even if it's being called in the form context, it'll still be a two dimensional array of objects, it'll just be a single group with a single row in it.
So ...
Code:
foreach ($data[0] as $group) {
foreach ($group as $row) {
// your rowid will be in $row->__pk_val
// elements will be in $row->tablename___fieldname
}
}
Don't use {rowid}, as that's just a placeholder for the current row in form view. So it'll work if your code is running from a delete in a form context, but won't work if it's being called from a list delete. And as explained, you have to assume your code will get called from a list delete - the same plugin is being triggered. So use $row->__pk_val.
For element data, use full element names, like $row->tablename___fieldname, or with the _raw suffix, $row->tablename___fieldname_raw (if your element is one with the concept of "value" and "label", like join elements).
If anyone wants to summarize that into the wiki, I'd appreciate it.
-- hugh
Edit
@troester 2021-02-11: corrected to $data[0] (see
@mirceat)