#################################################################### # Modify Multiple Records # Last edited 14 Aug 2000 # All subroutines copied from Links 2, with minor modifications #################################################################### # delicia - may need some work in validation for universal date translator #################################################################### # In html.pl, sub html_modify_search, after &html_record_form(); # add print qq|

Modify Multiple records at once: |; #################################################################### # Add the following subroutines to html.pl sub html_record_form_mult { # -------------------------------------------------------- # my (%rec) = @_; print &build_html_mult_record_form (%rec); } sub html_modify_mult_form { # -------------------------------------------------------- # The user has searched the database and requested to modify multiple # records at once. A form for each record is present along with a checkbox # on which record to use. # my ($status, @hits) = &query("mod"); my ($numhits) = ($#hits+1) / ($#db_cols+1); if (($numhits == 1) and !$in{'nh'}) { $in{'modify'} = $hits[$db_key_pos]; &html_modify_form_record(); return; } &html_print_headers(); print qq| $html_title: Modify Multiple Records.

$html_title: Modify Multiple $html_objects

<$font> Make any changes to the records and check off which records you want to save.
Your search returned $db_total_hits matches. |; if ($db_next_hits) { print "
<$font>Pages: $db_next_hits"; } # Go through each hit and convert the array to hash and send to # html_record for printing. Also add a radio button with name=modify # and value=key. if ($status ne "ok") { # Error searching database! print qq|

Error: $status|; } else { print "

"; for (0 .. $numhits - 1) { %tmp = &array_to_hash($_, @hits); print qq|
|; &html_record_form_mult (%tmp); print qq|
\n|; } if ($db_next_hits) { print "
<$font>Pages: $db_next_hits"; } } print qq|

|; &html_footer; print qq|

|; } sub html_modify_mult_results { # -------------------------------------------------------- # This page let's the user know that the records were successfully # modified. my ($success, $error) = @_; &html_print_headers(); print qq| $html_title: Record(s) Modified.
$html_title: $html_object(s) Modified.

<$font_title> $html_object(s) Modified

<$font> |; print "The following records were successfully modified: $success" if ($success); print "The following records were not successfully modified: $error" if ($error); print qq|

|; &html_footer; print qq|
|; } #################################################################### # In db.cgi, sub main, after elsif ($in{'modify_search'}) { &html_modify_search; } # Display the form to search for records to modify. # add elsif ($in{'modify_mult_form'}) { &html_modify_mult_form; } # Display multiple records to modify at one time. elsif ($in{'modify_mult_record'}) { &modify_mult_record; } # Modify multiple records at once. #################################################################### # Add the following subroutines to db.cgi sub modify_mult_record { # -------------------------------------------------------- # This routine will update multiple records at once. It expects # to find in %in a series of records to update. They will be of the # form field_name-key. # my ($key, %modify_list, %modify_rec, $rec_to_modify, @data, $key, $errstr, $succstr, $output, %errors); # First let's pick which records to modify and then separate them and store # them in their own hashes. $rec_to_modify = 0; foreach $key (keys %in) { # Build a hash of keys to modify. if ($in{$key} eq "modify") { $modify_list{$key} = 1; $rec_to_modify = 1; } ($key =~ /^(.*)-(.+)$/) and (${$modify_rec{$2}}{$1} = $in{$key}); } # Choke if we don't have anything to do. $rec_to_modify or (&html_modify_failure("no records specified.") and return); 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); } LINE: while () { (/^#/) and ($output .= $_ and next LINE); (/^\s*$/) and next LINE; chomp; @data = &split_decode($_); $key = $data[$db_key_pos]; # Now we check if this record is something we want to modify. If so, then # we make sure the new record is ok, if so we replace it. if ($modify_list{$key}) { $status = &validate_multiple_records(%{$modify_rec{$key}}); if ($status eq "ok") { $output .= &join_encode(%{$modify_rec{$key}}); $modify_list{$key} = 0; } else { $errors{$key} = $status; $output .= "$_\n"; } } else { $output .= "$_\n"; } } close DB; # Reprint out the database. 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 # Let's display an error message if we were unable to modify a record # for some reason. foreach $key (keys %modify_list) { if ($modify_list{$key}) { ($errors{$key}) ? ($errstr .= "$key: $errors{$key}") : ($errstr .= "$key: not found"); } else { $succstr .= qq~$key,~; } } chop($succstr); # Remove trailing delimeter &html_modify_mult_results($succstr, $errstr); } sub build_html_mult_record_form { # -------------------------------------------------------- # Builds a record form based on the config information. # my ($output, $field, $name); my (%rec) = @_; $output = "

"; foreach $field (@db_cols) { # Set the field name to field-key if we are doing multiple forms. $name = "$field-$rec{$db_key}"; if ($db_select_fields{$field}) { $output .= "\n"; } elsif ($db_radio_fields{$field}) { $output .= "\n"; } elsif ($db_checkbox_fields{$field}) { $output .= "\n"; } elsif ($db_form_len{$field} =~ /(\d+)x(\d+)/) { $output .= qq~\n~; } elsif ($db_form_len{$field} == -1) { $output = qq~\n$output~; } elsif ($db_form_len{$field} == -2) { $per_admin ? ($output .= qq~~) : ($output = qq~$output~); } else { $output .= qq~\n~; } } $output .= "
<$font>$field:" . &build_select_field($field, $rec{$field}, $name) . "
<$font>$field:" . &build_radio_field($field, $rec{$field}, $name) . "
<$font>$field:" . &build_checkbox_field ($field, $rec{$field}, $name) . "
<$font>$field:
<$font>$field:
<$font>$field:

\n"; return $output; } ####################################3 ### add to db.cgi sub validate_multiple_records { # -------------------------------------------------------- my ($col, @input_err, $errstr, $err, $line, @lines, $id, @rest); my (%record) = @_; foreach $col (@db_cols) { if ($record{$col} =~ /^\s*$/) { # entry is null or only whitespace if ($db_not_null{$col}) { # entry is not allowed to be null. push(@input_err, "$col (Missing)"); # so let's add it as an error } } else { # else entry is not null. if (defined($db_valid_types{$col}) && !($record{$col} =~ /$db_valid_types{$col}/)) { push(@input_err, "$col (Invalid)"); # but has failed validation so add } # it as an error. if ($db_sort{$col} eq "date") { push (@input_err, "$col (Invalid date format)") unless &date_to_unix($record{$col}); } (length($record{$col}) > $db_lengths{$col}) and push (@input_err, "$col (Too long. Max length: $db_lengths{$col})"); } } if ($#input_err+1 > 0) { # since there are errors, let's build foreach $err (@input_err) { # a string listing the errors $errstr .= "$err,"; # and return it. } chop $errstr; return $errstr; } else { return "ok"; # no errors, return ok. } } #################################################################### # Replace the following subroutines in db.cgi sub build_select_field { # -------------------------------------------------------- # Builds a SELECT field based on information found # in the database definition. Parameters are the column to build # and a default value (optional). my ($column, $value, $name) = @_; my (@fields, $ouptut); $name || ($name = $column); @fields = split (/\,/, $db_select_fields{$column}); if ($#fields == -1) { $output = "error building select field: no select fields specified in config for field '$column'!"; } else { $output = qq|"; } return $output; } sub build_checkbox_field { # -------------------------------------------------------- # Builds a CHECKBOX field based on information found # in the database definition. Parameters are the column to build # whether it should be checked or not and a default value (optional). my ($column, $values, $name) = @_; $name || ($name = $column); if (!$db_checkbox_fields{$column}) { return "error building checkboxes: no checkboxes specified in config for field '$column'"; } my @fields = split (/,/, $db_checkbox_fields{$column}); my @values = split (/\Q$db_delim\E/, $values); my ($field, $output); foreach $field (@fields) { (grep $_ eq $name, @values) ? ($output .= qq! $field\n!) : ($output .= qq! $field\n!); } return $output; } sub build_radio_field { # -------------------------------------------------------- # Builds a RADIO Button field based on information found # in the database definition. Parameters are the column to build # and a default value (optional). my ($column, $value, $name) = @_; my (@buttons, $button, $output); $name || ($name = $column); @buttons = split (/,/, $db_radio_fields{$column}); if ($#buttons == -1) { $output = "error building radio buttons: no radio fields specified in config for field '$column'!"; } else { foreach $button (@buttons) { $value =~ /^\Q$button\E$/ ? ($output .= qq| $button \n|) : ($output .= qq| $button \n|); } } return $output; }