Ronnie D. Jewell submitted this hack to the WebDB manager program. His modification allows one the ability to modify several prices at one time. With some slight modification one could also change any field with this hack. After your database is setup; changing prices is probably the most common task used by managers. In the original version, one must search for the record, click to indicate which record to modify, enter the new field data, then submit changes. This is fine and works well. However, what if one needs to modify the prices for an entire category or database for that matter? I have modified Selena's wonderful database manager program so managers could modify multiply prices with one click of the button. Most of the changes are in the database.setup file. Here is an overview of what needs to be added and modified. First, we need a "Modify Prices" button on the front page. This command will display the generic search form, after search criteria is enterd, the user submits the search and the Modify Price form is displayed. The user will make price changes and submit the changes. Here's how we do it. Open your setup file and follow the steps below. Step 1. In the section "Database Definition Variables" add the following lines: ####### start cut ####### @price_display_fields = ("SKU Number", "Description", "Price
Enter new price" ); @price_index_for_display = ($db{"product_id"}, $db{"description"}, $db{"price_r"} # set to match you price field also defined in this section ); ######## end ####### This will display only the Model Number, Description and Price.. There is no need to view he images or any other data since we are only interested in price. Step 2. In the "Display Frontpage Subroutine" add the following: This simply displays the "Modify Prices" button on the frontpage Step 3. Replace the "Modify Search Form Subroutine" with the following: ################################################################# # Modify Search Form Subroutine # ################################################################# sub modify_search_form { &generic_header("Search for an Item to Modify"); &generic_form_header; print qq~

Search the Database for Item to Modify

~; &display_generic_search_form; # if we are only wanting to modify prices; we will display the Modify Price form if ($form_data{'modify_price_button'} ne "") { print qq~

~; } else { print qq~

~; } &generic_form_footer; } Step 4. Replace the "search_results_body Subroutine" with the following: ################################################################# # search_results_body Subroutine # ################################################################# sub search_results_body { # Notice that in this subroutine we have access to the # $total_row_count hits variable if we want to display it. if ($total_row_count > $max_rows_returned) { print qq~ Your search turned up $total_row_count hits, but I am designed to only show you $max_rows_returned at a time. I suggest you narrow your search criteria a bit.

~; } else { print qq~ Your search turned up $total_row_count hits.

~; } # We next need to display the table header. Make sure # that in the case of modify and delete we add a colmun so # that the user can select items to be modified or # deleted. print qq~ ~; if ($form_data{'search_and_display_for_deletion_button'} ne "") { print "\n"; } elsif ($form_data{'search_and_display_for_modification_button'} ne "") { print "\n"; } ### rdj added for price modifications ###### elsif ($form_data{'search_and_display_for_price_button'} ne "") { foreach $header (@price_display_fields) { print "\n"; } print ""; foreach $row (@database_rows) { @fields = split (/\|/, $row); print qq~ ~; foreach $index (@price_index_for_display) { $fields[$index] =~ s/~p~/\|/g; $fields[$index] =~ s/~nl~/\n/g; # Also, we will check to see if the current field being # displayed happens to be an email field. If so, we will # make it a clickable mailto link. # # Notice that you would use the exact same method for # making a clickable URL. if ($index == $index_for_email) { print qq~ \n~; } elsif ($index == $index_for_price) { ## you may need to change the name of this input to match your price field value ## print qq~ \n~; } else { print "\n"; } } # End of foreach $index (@db_index_for_display) print ""; } print "
Select Items to DeleteSelect Item to Modify$header
$fields[$index]$fields[$index]
"; &search_results_footer; exit; } #end rdj added elsif price routine foreach $header (@db_display_fields) { print "$header\n"; } print ""; # Basically, we will display a simple HTML table to show # all of the rows which satisfied the search criteria # entered by the user. # # The idea is this. We will go through the @database_rows # (which was given to us by db-lib.pl and contains all of # the hits) one element at a time and convert the pipe # delimited database row into an HTML row. foreach $row (@database_rows) { @fields = split (/\|/, $row); if ($form_data{'search_and_display_for_modification_button'} ne "") { print qq~ ~; } if ($form_data{'search_and_display_for_deletion_button'} ne "") { print qq~ ~; } # Of course, we will only actually display fields which we # have defined as displayable in @db_index_for_display and # we will be careful to convert all pipe sybmbols and new # lines from our db representation values into their # original forms. foreach $index (@db_index_for_display) { $fields[$index] =~ s/~p~/\|/g; $fields[$index] =~ s/~nl~/\n/g; # Also, we will check to see if the current field being # displayed happens to be an email field. If so, we will # make it a clickable mailto link. # # Notice that you would use the exact same method for # making a clickable URL. if ($index == $index_for_email) { print qq~ $fields[$index]\n~; } else { print "$fields[$index]\n"; } } # End of foreach $index (@db_index_for_display) print ""; } print ""; } Step 5. In the "search_results_footer Subroutine" after if ($form_data{'search_and_display_for_modification_button'} ne "") { &add_modify_data_entry_form; print qq~

~; } ### add these lines ### if ($form_data{'search_and_display_for_price_button'} ne "") { print qq~

~; } ### end add ### Well thats the end of the modifications needed in the setup file.. Now we will move on to the db_manager.cgi file. Step 1. Add three elsif statements to the other 11 routines (about 1/3 the way down the script): You should see these lines elsif ($form_data{'submit_addition'} ne "") { &submit_addition; exit; } #### add these three subroutines here ### elsif ($form_data{'modify_price_button'} ne "") { &modify_search_form; exit; } elsif ($form_data{'search_and_display_for_price_button'} ne "") { &search_and_display_for_modification; exit; } elsif ($form_data{'submit_price_modification_button'} ne "") { &submit_new_price; exit; } ### end addition #### Step 2. Add this subroutine between the submit_addition and submit_modify subroutines: ####################################################################### # Submit a price change # # added by RDJ 11/28/98 # ####################################################################### # The user might also be submitting a modification to the # database. sub submit_new_price { # The first thing we must do is make sure that they # actually chose a database item to modify. If they did # not, we better warn them and stop processing. if ($form_data{'item_to_modify'} eq "") { &no_item_submitted_for_modification; exit; } # If they did choose an item, we need to find that items # so that we can modify it. To do so, we'll open the data # file and read through it a line at a time. We'll then # split up each line into its fields and compare the id # number given to us by the suer against the id number of # the current line. If it is not the same, we will add # the entire line to a variable called $new_data (By the # end of this, $new_data is going to hold the entire # contents of our database). @item_to_modify = &SplitParam($form_data{'item_to_modify'}); @new_price = &SplitParam($form_data{'price_r'}); $p = 0; foreach $item (@item_to_modify) { open (DATABASE, "$data_file_path") || &file_open_error ("$data_file_path", "Modify item", __FILE__, __LINE__); while () { $line = $_; chop $line; @fields = split (/\|/, $line); if ($fields[$index_of_db_id_number] ne $item) { $new_data .= "$line\n"; } # If the id numbers ARE equal, however, it means that we # have found the database row that needs to be modified. # # First, we will save the old line in a variable $old_row. # We are going to need that value when we report what # happened in the log file. # # Then, we will go through the basic user-definable fields # checking to see which fields the user has asked to # modify (Only fields which have a $form_data value, will # be modified.) # # Notice, that we will append this row to $new_row one # field at a time. If the user has not submitted a # change, we'll grab the value from the old row. else { $old_row = "$line"; $already_added = "no"; $already_changed = "no"; if ($fields[$index_of_db_id_number] eq $item) { for ($i=0; $i <= (@db_user_definable_field_order-1); $i++) { $index = @db_user_definable_field_order[$i]; if ($form_data{$index} ne "") { $new_row .= "$new_price[$p]\|"; } else { $new_row .= "$fields[$i]\|"; } } # End of for ($i=1; $i <= @db_user_definable_field_order; $i++); $already_changed = "yes"; } #end if if (($already_added ne "yes") && ($already_changed ne "yes")) { $new_data .= "$line\n"; $already_added = "yes" } $new_data .= "$new_row"; # Now we will complete the row by adding all of the # administrative variables like the date and the # authentication values. Notice that if the person who is # modifying the data is an admin, we will use the group # and user values from the old row instead of changing it # to admin. That way the original poster will still be # able to modify it. $when_modified = &get_date; $who_modified = $session_username; if ($session_group eq "admin") { $group = $fields[$index_of_group_who_modified]; $who_modified = $fields[$index_of_who_modified]; } else { $group = $session_group } $new_data .= "$when_modified|$who_modified|$group|$fields[$index_of_db_id_number]\n"; $new_row .= "$when_modified|$who_modified|$group|$fields[$index_of_db_id_number]"; } # End of else } # End of while () close (DATABASE); # Now that we have appended the entire database as well as # the modified row to $new_data, it is time to change the # data file. However, first, we must make sure that the # user is performing a legal operation. The next if test # asks 1) is the user the original poster of the database #row or are they in the same group as the user who posted # it (provided that group is not the default "user" group # which everyone is assigned to, 2) or are they an # administrator. If the user passes this test and the # admin has set the script to use authentication, the # script will add the overwrite the old database with the # contents of $new_data, protecting it with a lockfile as # we did for addition. if ((($session_username eq $fields[$index_of_who_modified]) || (($session_group eq $fields[$index_of_group_who_modified]) && ($session_group ne "user"))) || ($session_group eq "admin") || ($should_i_authenticate ne "yes")) { &get_file_lock("$location_of_lock_file"); open (DATABASE, ">$data_file_path") || &file_open_error ("$data_file_path", "Modify Item", __FILE__, __LINE__); print DATABASE "$new_data"; close (DATABASE); # We will also add the modification information to the log # file. open (LOG_FILE, ">>$location_of_log_file") || &file_open_error ("$location_of_log_file", "Modify Item", __FILE__, __LINE__); print LOG_FILE "MODIFY_NEW\|$new_row|MODIFIED BY here $item $session_username\n"; print LOG_FILE "MODIFY_OLD\|$old_row\n"; close (LOG_FILE); &release_file_lock("$location_of_lock_file"); $success = "1"; } else { &unsuccessful_modification_message; } $new_data = ""; $new_row = ""; $p = $p + 1; } # end foreach if ($success == 1) { &successful_modification_message; } } # end sub price Well thats it... Now you can change prices on any searched records with the click of one button... Good Luck...