Gossamer Forum
Home : Products : DBMan : Customization :

admin notify changed fields

Quote Reply
admin notify changed fields
I want to include in email to admin the original value as well as new value when user modifies a record. i've seen hack that does this; however, this hack sends the mail before the user actually saves the mod. so the admin would be notified of change even if user doesn't save the change. seems i should be able to save the original value of %rec in a new variable, such as %orig, and pass that to modify success. i am too much a perl novice to figure out how to do this. how would i declare the variable? i added my (%orig) in sub modify_record in db.cgi. i also added:
my (%orig) = %rec; in sub html_modify_form_record { after %rec is retrieved. i added %orig to the email line. this isn't working. i must be leaving out something. can anyone help? thanks!

Quote Reply
Re: [delicia] admin notify changed fields In reply to
i'm trying to figure out how to compare original record with the new record. i have read posts here that say it needs to be done in the part of code i have indicated here. but i can't figure out how to access the individual fields. i thought $rec{$col} would be the original field and $in{$col} would be the new data. if they are different i want to store them to a variable ($message) and then pass $message to html_modify_success where i generate the email (similar to the way an error is passed to html_modify_failure). can someone tell me what i need to do to make the comparison? thanks!
in db.cgi sub modify_record i have:

Code:


my ($status, $line, @lines, @data, $output, $found, %rec, $key, $num_files, @files, $file);
my ($message, $col);
if ($auth_modify_own and !$per_admin) {
%rec = &get_record($in{$db_key});
unless ($rec{$db_cols[$auth_user_field]} eq $db_userid) {
&html_modify_failure("You are not authorized to modify this record");
return;
}
}
$status = &validate_record; # Check to make sure the modifications are ok!
if ($status eq "ok") {
open (DB, "<$db_file_name") or &cgierr("error in modify_records. unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) { flock(DB, 1); }
@lines = <DB>; # Slurp the database into @lines..
close DB;
$found = 0; # Make sure the record is in here!
LINE: foreach $line (@lines) {
if ($line =~ /^$/) { next LINE; } # Skip and Remove blank lines
if ($line =~ /^#/) { $output .= $line; next LINE; } # Comment Line
chomp ($line);
@data = &split_decode($line);

if ($data[$db_key_pos] eq $in{$db_key}) {
# If we have userid's and this is not an admin, then we force the record to keep it's own
# userid.
if ($auth_user_field >= 0 and (!$per_admin or !$in{$db_cols[$auth_user_field]})) {
$in{$db_cols[$auth_user_field]} = $data[$auth_user_field];
}
####### try hack to show fields that are modified
foreach $col (@db_cols) {
if ($rec{$col} ne $in{col}) {
$message .= "$col" . "$rec{$col}" . "changed to" . "$in{$db_cols{$col}}\n";
}
}
#######

Quote Reply
Re: [delicia] admin notify changed fields In reply to
I'm wondering why you used

Code:
$message .= "$col" . "$rec{$col}" . "changed to" . "$in{$db_cols{$col}}\n";

and not

Code:
$message .= "$col" . "$rec{$col}" . "changed to" . "$in{$col}\n";

That may be your problem. Otherwise, it looks like it should work.


JPD
----------------------------------------------------
JPDeni's DBMan-ual
How to ask questions the smart way.

Last edited by:

JPDeni: Mar 15, 2005, 12:36 AM
Quote Reply
Re: [JPDeni] admin notify changed fields In reply to
i think that's what i tried the first time and it didn't work. i'll try again. EDIT: i tried again and it still doesn't work. this is what the email message has:

jack|23|jack|2|wildcats@delicia.com|Configuration Management|No|sdf ierwers sdf sd sd fsdfsd dsf||23-Feb-2005|15-Mar-2005||no||xxxxx

it's listing the entire record straight out of the db file with delimiters and all, instead of listing individual fields. also, it's only listing them once. i think it's listing the new record, not the original. on the above, i modified to change category from Standard to Configuration Management. so the email should look like:

Standard changed to Configuration Management

Last edited by:

delicia: Mar 15, 2005, 6:06 AM
Quote Reply
Re: [delicia] admin notify changed fields In reply to
Can you post the rest of your code? It looks like the email is sending you the result of &join_encode(%in) instead of the $message variable.


JPD
----------------------------------------------------
JPDeni's DBMan-ual
How to ask questions the smart way.

Last edited by:

JPDeni: Mar 15, 2005, 7:37 AM
Quote Reply
Re: [JPDeni] admin notify changed fields In reply to
thanks for looking. here's the rest:

Code:


####### try hack to show fields that are modified
foreach $col (@db_cols) {
if ($rec{$col} ne $in{$col}) {
$message .= "$col" . "$rec{$col}" . "changed to" . "$in{$col}" . "\n";
}
}
#######
$output .= &join_encode(%in);
$found = 1;
}
else {
$output .= $line . "\n"; # else print regular line.
}
}
if ($found) {
open (DB, ">$db_file_name") or &cgierr("error in modify_records. unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) {
flock(DB, 2) or &cgierr("unable to get exclusive lock on $db_file_name.\nReason: $!");
}
print DB $output;
close DB; # automatically removes file lock
&auth_logging("modified record: $in{$db_key}") if ($auth_logging);
&html_modify_success("$message");
# &html_modify_success;
}
else {
&html_modify_failure("$in{$db_key} (can't find requested record)");
}
}
else {
&html_modify_failure($status); # Validation Error
}
}

Quote Reply
Re: [delicia] admin notify changed fields In reply to
You don't need the quotes in &html_modify_success("$message"); but it probably doesn't matter that you have them.

Following the path of the variable, which is the way I debug things, the next thing to do is to see the code in sub html_modify_success. How are you passing the variable? What happens to it after that? You don't need to include all the code, just the stuff that concerns the variable that was passed from the subroutine.

One of the frustrating things about working with DBMan, is that it's hard to access the variables directly. So we're not really sure whether the problem is that the $message variable isn't collecting your data or that it's not being printed out.

Here's something to try. Temporarily remove the $message variable from the "my" command, so that it will be a global variable and available throughout the program. Go to sub cgierr and add the following just before the line

print "\n</PRE>";

Code:
print "Message: $message";


Then set $db_debug = 1; in the .cfg file. When you modify a record, you should get it listed at the bottom of the debug information.


JPD
----------------------------------------------------
JPDeni's DBMan-ual
How to ask questions the smart way.
Quote Reply
Re: [JPDeni] admin notify changed fields In reply to
ok, here's the debug which is great except i failed to include spaces:

Message: Order4changed to5
CategoryStandardschanged toProject Management

i already had debug turned on but didn't know how to get it to show message -- thanks for the tip!

here's html_modify_success:

my (%rec) = &get_record($in{$db_key});
my ($message) = $_;
if ($admin_notify && !$per_admin) {
open (MAIL, "$mailprog") || &cgierr("Can't start mail program");
print MAIL "To: $admin_email\n";
print MAIL "From: $admin_email\n";
print MAIL "Subject: $html_title Record\n\n";
print MAIL "The following record has been modified:\n\n";
print MAIL "$message\n";
close (MAIL);
}

i see now that i have another "my". i'll test again and edit this post.
EDIT: ok i changed above to $message = $_;

now message debug is:
Message: jack|23|jack|6|wildcats@delicia.com|Configuration Management|No|sdf ierwers sdf sd sd fsdfsd dsf||23-Feb-2005|15-Mar-2005||no||xxxxx

both emails were bad like the latest Message. so removing my in db.cgi made the message variable correct in debug, but had no effect on email. removing my from html.pl messed up message in debug too.

Last edited by:

delicia: Mar 15, 2005, 2:26 PM
Quote Reply
Re: [delicia] admin notify changed fields In reply to
thanks for all your help. i have it working now and will share so others may want it. purpose of this mod is to show only the changed fields in the email notification to admin when a user modifies a record.

in db.cgi sub modify records, add near top of sub:

my ($message, $col);

later in sub, BEFORE:
$output .= &join_encode(%in);
$found = 1;

add:
####### hack to show fields that are modified
foreach $col (@db_cols) {
if ($rec{$col} ne $in{$col}) {
$message .= "$col " . "$rec{$col} " . "changed to " . "$in{$col}" . "\n";
}
}
#######

near end of sub, change:

&html_modify_success;

to:

&html_modify_success ($message);

###############
in html.pl, sub html_modify_success

insert new first line of sub:
my $message = shift;

then add mail routine after my (%rec) so you have:

my $message = shift;
my (%rec) = &get_record($in{$db_key});
if ($admin_notify && !$per_admin) {
open (MAIL, "$mailprog") || &cgierr("Can't start mail program");
print MAIL "To: $admin_email\n";
print MAIL "From: $admin_email\n";
print MAIL "Subject: $html_title Record\n\n";
print MAIL "The following record has been modified:\n\n";
print MAIL "Record: $in{$db_key}\n";
print MAIL "$message\n";
close (MAIL);
}
##### end hack

########################
in cfg add a flag if you want to send an email to admin when record added or modified:
$admin_notify = 1; # set to zero if you don't want email

Quote Reply
Re: [delicia] admin notify changed fields In reply to
Excellent!

I have had no end of problems using $_ . I don't really know why. I have much better luck using @_ which really does the same thing if you only have one variable. But shift works just as well.

Well done.


JPD
----------------------------------------------------
JPDeni's DBMan-ual
How to ask questions the smart way.
Quote Reply
Re: [JPDeni] admin notify changed fields In reply to
i don't understand either one, but copied another sub.
Quote Reply
Re: [delicia] admin notify changed fields In reply to
Now that I've been thinking about this, I do know why $_ doesn't work. When you pass variables from one subroutine to another, the variables are held in an array, which allows you to pass any number of values that you want. In your case, there was only one, so you could have used my $message = @_; and it would have put the first value in the passed array (the only value in this case) into the $message variable. If you had passed more than one, you could have used my ($message, $othervariable) = @_; and it would have put the first two values in the array into the variables.

Your use of shift also assumes the existence of an array. The way shift works is to return the first element of an array and remove that element from the array, moving all the others up by one. Most times you would actually name the array, as in $message = shift (@array); , but you didn't need to this time because the array you are shifting is the one that was sent from the other subroutine. Perl assumes that's the one you want to use.

I hope I haven't confused you with this, but it was a neat "ah-hah!" experience for me and I thought I'd share it. :-)


JPD
----------------------------------------------------
JPDeni's DBMan-ual
How to ask questions the smart way.
Quote Reply
Re: [JPDeni] admin notify changed fields In reply to
thanks. i think i'll print this explanation and save it in my dog-eared Learning Perl book!