Audiot logging for editor.
Audiot logging for editor.
Hey guys,
I need to add some sort of audit logging for create/delete and edit functions on the data-tables editor. Any examples and help
would be much appreciated.
I'm looking to dump data into an audit table on each action.. something really simple.. doesn't have to dump username or anything.. just data trail.. date+action+data_before+data_after
Example for an edit
[field: date] = {2017-01-10 : 19:05:23}
[field: action] = {edit}
[field: data_before] = {id=1, name="foo baarson", age=110, info="too old"}
[field: data_after] = {id=1, name="bar fooson", age=110, info="too old"}
Example for a create
[field: date] = {2017-01-10 : 19:05:23}
[field: action] = {create}
[field: data_before] = {}
[field: data_after] = {id=1, name="bar fooson", age=110, info="too old"}
Example for a delete
[field: date] = {2017-01-10 : 19:05:23}
[field: action] = {delete}
[field: data_before] = {id=1, name="foo baarson", age=110, info="too old"}
[field: data_after] = {}
This way you can write a recovery script to the side.. like an 'undelete' button.. or even have one inline in the table.
This question has an accepted answers - jump to answer
Answers
The server-side events would be the way to do this. There is an audit log example on the page - although obviously you'll need to customise it to suit your exact needs.
Allan
That's perfect, thanks!
This is great functionality built into the examples. I have implemented this as well, but am struggling with how to capture what the values were before the update.
I'd like to capture the data before the field(s) are edited and store them as a JSON object in the log table. That way I could implement the log in such a way as to show 'user x changed value y from a to b'. What I do now is store the values changed into a JSON field in my log table using:
I tried expanding the example to use this: (I'm using Datatables / Editor PHP libraries)
Here the
$values
are the client-side ones (ie. edited). I can't seem to wrap my head around how to grab what the values were before the edit.EDIT: I see now where the
preEdit
andpostEdit
only differ in the sense of thepostEdit
only runs after the data is successfully entered in the db.Any ideas / pointers appreciated..
Thanks.
N
Hi,
What I would suggesting doing in this case is getting the values as they are before the editing, directly from the database (Editor from the client-side doesn't submit the old values - just the new ones).
So you could do something like:
The full reference documentation for the database class is available here.
Allan
@allan : AWESOME. Exactly what I need. I don't know how I overlooked it but I had been looking for the docs on the database class. Thanks so much!
N
@allan Alright I am well on the way I think. Thanks for the pointers. This is what I am currently using:
logChange function:
Outside my
Editor::inst
Editor definitions:
This works but while my log table
newValues
column has only the changed columns included in the JSON (Im usingformOptions: submit->changed
in the main), theprevValues
column contains all the db fields (clearly because I am selecting all the fields with theselect:
method).Working to try to detect somehow and only store in the
prevValues
field in the log table the fields that were changed on edit, so basicallynewValues
would only contain changed fields, andprevValues
would contain only the same fields, but with the previous values.Thanks for posting that!
To get only the changed field's values, I think you'd need to loop through the list of fields that was submitted in order to extract that information.
Allan
I'm stuck on this again. Forgive the silly code as I am just testing. In looking at the database docs, I should be able to pass an array of fields to the select statement:
(I do
array_shift
because the table name is appended at the start of the array in the$values
such as[weir_ips: [name => 'test]])
Here the
$_SESSION['logtest']
ends up being the key names (fields) changed in the editor operation. So I try to pass that to my query, to get the values of those fields to enter into the log as the previous values. Except when I check the log table it seems to be an empty array for the prevValues.[]
I can echo `$_SESSION['logtest'] after an edit and it shows the key(s) correctly:
My thought here was I could pass that in, select only those fields and then pass them to my
logChange()
function above.I must be overlooking something stupid. (likely I just dont understand some of the basics).
Scratching my head.... :-)
I may be wrong (again...) but I didn't know PHP accepts that array notation: [ 'id' => $id ]
Have you tried "array( 'id' => $id )" ?
@tangerine I don't think PHP does natively but that is using the Editor Database class and is pulled from one of the examples. They query works fine if I specify * in the place of
$_SESSION['logtest']
. It just returns all the fields.Got it working. Not sure where my mind was, but the following seems to work great. I end up with a row in my log table with a user, action, date, id of the row that was edited, one JSON field with the keys and new values and one JSON field with keys and old values. Should be easy enough to parse that back out and display it.
logChange()
:Editor
PHP init: (I usedarray_shift
because I am using joins in my Editor instance, andvalues
returned a two-dimensonial array, with one element. The key for that element was the table name. The single element is an array of the changed values). I grab those and proceed.Thanks for all the great advice.
N
From 5.4+ it does. For 5.3 and before you'd need to use
array()
to create a new array.Looks good - great to hear you've got it working as you need now!
Allan
Current PHP version: 5.6 Not Work,
Please Help
Looks like you are using a single array (not nested arrays). The
array_keys()
function needs an array. Try removing thearray_shift()
.N
Thank you very much for your help
"fetch" not working My Current PHP version: 5.6 Could it be because of this?
[ 'id' => $id ]
My Database Results:
PrevValues = "{"first_name":"Angelica","last_name":"Ramos","position":"Chief Executive Officer (CEO)","office":"London","extn":"5797","start_date":"2017-12-21 01:13:00","salary":"1200000"}"
New Values = "Angelica1"
Are you still getting an SQL error? What are the values of the variables you are passing into the
select
function?Allan