#!/usr/bin/perl # Created: 08/02/98 # Copyright (c) 1998-1999-2000-2001 i-Soft, LLC BEGIN { $cwd = $ENV{'SCRIPT_FILENAME'} || $0; $cwd =~ s/\\/\//g; my(@cwds) = split(/\//,$cwd); pop(@cwds); $cwd = join("/",@cwds); # Manual Current Working Directory settings. # uncomment the appropriate line below (remove the first pound sign) # and set manually as shown in the example: #$cwd = "/home/InfoDB/www/cgi-bin"; #(UNIX Example) #$cwd = "D:/webs/InfoDB/cgi-bin"; #(NT Example) my($pluginDir) = ("$cwd/plug-ins"); unshift(@INC, $pluginDir); } use CGI::Carp; # Global Settings $script_name ="main_store.cgi"; my($exe_version) ="no"; my($publicKey) ="serno.cgi"; my($main_setup) ="main_store_cfg.cgi"; my($lang_setup) ="main_store_lng.cgi"; my($version) = "2.12.45"; my($last_update) = "08/13/2001"; # Set the version into the ENV so # we can see it on error messages: $ENV{'INFODB_VERSION'} = $version; # Clear the buffer $| = 1; # Debug 1=yes, 0=no $debug = 0; my($content_type) = "Content-type: text/html\n\n"; if($debug){ print "$content_type\n
\n"; } else{ print $content_type; } # Get the remote host: my($remote_host) = $ENV{'REMOTE_ADDR'} || $ENV{'REMOTE_HOST'}; $form_data{'user_host'} = $remote_host; # Try to set the permissions on the # basic files in the cgi-bin chmod(0755,"$cwd/$main_setup"); chmod(0755,"$cwd/$lang_setup"); chmod(0777,"$cwd/log_files"); chmod(0777,"$cwd/orders"); chmod(0777,"$cwd/user_carts"); # The location of the setup file my($pubkeyfile) = "$cwd/$publicKey"; # Read and parse the incoming form data. %form_data = &read_and_parse_form_data; # We need to tell the script where to find the # supporting libraries and setup files. $store = $form_data{'store'} || ""; if($store ne ""){ $config_file = "$cwd/$store.cgi"; $main_setup = "$store.cgi"; $language_file = "$cwd/$store\_language.cgi"; } else { $config_file = "$cwd/$main_setup"; $language_file = "$cwd/$lang_setup"; } if($debug){ print "$config_file\n"; print "$language_file\n"; } # We load the libraries making sure we load the error # library first just in case there is a problem with # the other library and supporting files. # If the store name is empty, this would mean that # we have not read in the cfg file. If so, we # read in the basic configuration information and # put them into associative arrays. %cf = &read_config_file($config_file); %strings = &read_config_file($language_file); if($cf{'maintenance_mode'} eq "yes"){ &bad_order_note("Store Closed",$strings{'maintenance_message'}); } # Store Search Parameters my($CFkey); my($CFvalue); while(($CFkey,$CFvalue) = each(%cf)){ if($CFkey =~ /query/ig){push(@db_query_criteria,$CFvalue);} } # Get date/month strings my($STRkey); my($STRvalue); %days = (); %months = (); while(($STRkey,$STRvalue) = each(%strings)){ if($STRkey =~ /^day/ig){$days{$STRkey} = $STRvalue;} if($STRkey =~ /^month/ig){$months{$STRkey} = $STRvalue;} } # Get the mail lib in case there are errors my($mail_lib) = "$cwd$cf{'plug_in_path'}/email.pl"; &require_supporting_libraries(__FILE__, __LINE__,"$mail_lib"); # Dates ($date, $short_date) = &get_date; if($debug){ print "$date, $short_date\n"; } if(defined $ENV{'WINDIR'}){$cf{'os'} = "nt";} if($form_data{'display_cart_after_purchase'} ne ""){ $cf{'display_cart_after_purchase'} = $form_data{'display_cart_after_purchase'}; } # Now that we know the Current Working Directory, # let's get the base and script URL's as well. my($base_url) = &base_url; $script_url = $cf{'script_url'} || ""; if($script_url eq ""){ $script_url = &script_url; } if($cf{'base_directory'} ne "cwd"){ $cwd = $cf{'base_directory'}; } # Try to auto-set the permissions # on some of the directories &chmod_directories; # Web Site URL $web_site_url = $cf{'web_site_url'} || ""; if(($web_site_url ne "")&&(substr($web_site_url,0,4) !~ /http/ig)){ $web_site_url = "http://$web_site_url"; $cf{'web_site_url'} = $web_site_url; } if($web_site_url eq ""){ my($myscript) = $script_name; if ($exe_version eq "yes"){ $myscript =~ s/cgi/exe/; } $web_site_url = $script_url; $web_site_url =~ s/$cf{'cgi_directory_name'}\/$myscript$//i; chop $web_site_url; $cf{'web_site_url'} = $web_site_url; } # Secure Page URL for styles.css page: $secure_page_url = $web_site_url; if(($cf{'secure_page_url'} ne "")&&($cf{'order_form_secure'} eq "yes")){ $secure_page_url = $cf{'secure_page_url'}; } # cgi directory name; my($cgidir) = $cf{'cgi_directory_name'}; # Set all of the remaining support library variables if($cf{'web_server_document_root'} eq ""){ $cf{'web_server_document_root'} = $ENV{'DOCUMENT_ROOT'}; } my($docRoot) = $cf{'web_server_document_root'}; if($docRoot eq ""){ $docRoot = $cwd; $docRoot =~ s/$cf{'cgi_directory_name'}//; $cf{'web_server_document_root'} = $docRoot; } # Now, set a few working variables $secure_script_url = $cf{'secure_script_url'} || ""; if(($secure_script_url eq "")||($cf{'order_form_secure'} eq "no")) { $secure_script_url = $script_url; } # Change max rows: if($form_data{'max_rows'} ne ""){ $cf{'max_db_rows_returned'} = $form_data{'max_rows'}; } # Set page: if($form_data{'page'} ne ""){ $page = $form_data{'page'}; $ENV{'INFODB_PAGE'} = $page; } else{ $form_data{'page'} = $cf{'store_front_page'}; $page = $cf{'store_front_page'}; } my($Process) = $form_data{'process_order'} || ""; if($Process ne ""){ $page = ""; $form_data{'page'} = ""; } if(defined $form_data{'database'}){ my($DB) = "$form_data{'database'}.dat"; my($DbPath) = "$cwd$cf{'database_path'}/$DB"; # get rid of attempts to insert illegal characters $DbPath =~ s/[\&\`\;\*\|\^\!\(\)\{\}\<\>\n\l\r\\]//gs; # Check for only word characters. # disallow "../" if(($DbPath =~ /^[\w\._-]+$/)&&($DbPath !~ /\.{2}\//g)){ print "Invalid database filename: $DbPath"; exit; } unless(-e "$DbPath"){ print "Cannot find database file: $DbPath"; exit; } $cf{'database_name'} = $DB; } if(defined $form_data{'cart_id'}){ $cart_id = $form_data{'cart_id'}; if(($cart_id =~ /\%\%cart_id\%\%/i)|| ($cart_id =~ /\%25\%25cart_id\%25\%25/i)) { $form_data{'cart_id'} = ""; $cart_id = ""; } } # Return Variables from CC Processors if((defined $form_data{$cf{'order_number_field'}})&& ($form_data{$cf{'order_number_field'}} ne "")){ $cart_id = $form_data{$cf{'order_number_field'}}; $form_data{'process_order'} = "yes"; } # 1/1/99 Added Store Type form variable. # If the script sees an incoming form variable of store # type, it will use that instead of the default store type # listed in the cfg file. my($store_type) = $form_data{'store_type'} || "database"; if($store_type =~ /htm/i){ $cf{'use_inventory_control'} = "no"; } else{ $cf{'use_inventory_control'} = $cf{'use_inventory_control'} || ""; } # $category is the category name without the underscores. # $format_category is the category name with underscores # so that it is a unique single word when the scipt does # a product category search. my($category) = $form_data{'category'} || ""; my($format_category); if($category ne ""){ $format_category = $form_data{'category'}; $category =~ s/\_/ /g; $format_category =~ s/\s/\_/g; # Now, to make it look nice, we set the first letter # of each word in the $category name to upper case. my(@uc_category) = split(/ /,$category); my(@new_category) = (); my($word); foreach $word (@uc_category){ push(@new_category, "\u$word"); } $category = join(" ", @new_category); if($form_data{'category'} =~ /^all$/i){ $form_data{'category'} = ""; } } if ($form_data{'admin'}) { print "InfoDB Version $version no longer supports Online Admin Functions."; exit; } # Inventory Control Plugin my($plugInName) = $cf{'inventory_plugin_name'} || ""; my($inventoryPlugin) = "$cwd$cf{'plug_in_path'}/$plugInName"; if(($cf{'use_inventory_control'} eq "yes")&& (-e $inventoryPlugin)){ &require_supporting_libraries(__FILE__, __LINE__,$inventoryPlugin); } # set the incoming button variables for both # plain buttons or graphic style buttons. $view_cart = $form_data{'view_cart'} || $form_data{'view_cart.x'} || $form_data{'cancel_change'} || $form_data{'cancel_change.x'}; $add_to_cart = $form_data{'add_to_cart'} || $form_data{'add_to_cart.x'}; $change_quantity = $form_data{'change_quantity'} || $form_data{'change_quantity.x'}; $submit_change = $form_data{'submit_change'} || $form_data{'submit_change.x'}; $delete_items = $form_data{'delete_items'} || $form_data{'delete_items.x'}; $submit_delete = $form_data{'submit_delete'} || $form_data{'submit_delete.x'}; $checkout = $form_data{'checkout'} || $form_data{'checkout.x'}; $process_order = $form_data{'process_order'} || $form_data{'process_order.x'}; $search_request = $form_data{'search'} || $form_data{'search.x'}; $continue_shopping = $form_data{'continue'} || $form_data{'continue.x'}; $storefront = $form_data{'storefront'} || $form_data{'storefront.x'}; $main_page = $form_data{'mainpage'} || $form_data{'mainpage.x'}; $previous_products = $form_data{'previous_products'} || $form_data{'previous_products.x'}; $next_products = $form_data{'next_products'} || $form_data{'next_products.x'}; # Finally we submit the incoming form data to some # security checks. &error_check_form_data($page); # The purpose of a unique cart is so that every # customer (user) can have a unique cart which # contains their specific purchases. my(%cookie); my($ip_Log); if($cart_id eq ""){ if($cf{'use_cookies'} eq "yes"){ %cookie = &get_cookie(); $cart_id = $cookie{'cart_id'}; if($cart_id eq ""){ &delete_old_carts; $cart_id = &assign_a_unique_shopping_cart_id; &printJavaCookieScript($cart_id); } $form_data{'cart_id'} = $cart_id; } if($cart_id eq ""){ &delete_old_carts; ($cart_id,$ip_Log) = &get_cart_id_from_address_log; } } $users_cart_path = "$cwd$cf{'user_carts_path'}/$cart_id.cart"; # Now that the script has created the entire environment # in which it must operate set, it's time to provide # the logic for it to determine what it should do. # # The logic is broken down into a series of "if" tests. # Test for query fields first my($are_any_query_fields_filled_in) = "no"; my($query_field); foreach $query_field (@db_query_criteria){ my(@criteria) = split(/\|/, $query_field); if((defined $form_data{$criteria[0]})&&($form_data{$criteria[0]} ne "")){ $are_any_query_fields_filled_in = "yes"; } } if($are_any_query_fields_filled_in eq "yes"){ $search_request = "yes"; } # Now for buttons if($add_to_cart ne "") # Add To Cart { &add_to_the_cart; exit; } elsif($view_cart ne "") # View Cart { &display_cart_contents; exit; } elsif($submit_change ne "") # Submit Change Quantity { &modify_quantity_of_items_in_cart; exit; } elsif($submit_delete ne "") # Submit Delete { &delete_from_cart; exit; } # Go To Checkout elsif($checkout ne "") { &display_order_form; exit; } # Process Order elsif($process_order ne "") { &process_order_form; exit; } # Display Default Home.htm elsif($storefront ne "") { &output_frontpage; exit; } # Display Default Main.htm elsif($main_page ne "") { &redirect_user("$cf{'web_site_url'}/$cf{'store_main_page'}","0",""); exit; } elsif($form_data{"version"} ne "") { &redirect_user("$cf{'web_site_url'}/$cf{'store_main_page'}","0",""); exit; } # Any other buttons elsif(($page ne "" || $search_request ne "" || $continue_shopping ne "" || $are_any_query_fields_filled_in eq "yes") && ($storefront eq "")) { &display_products_for_sale; exit; } # Else, just display the storefront page. else { &output_frontpage; exit; } exit; # From here on out we will define the logic of the # subroutines called in the "if" statements above. # ------------------------------------------------------------------- sub chmod_directories { # The read only directories chmod(0755,"$cwd$cf{'templates_path'}"); chmod(0755,"$cwd$cf{'plug_in_path'}"); # Writable Directories chmod(0777,"$cwd$cf{'log_files_path'}"); chmod(0777,"$cwd$cf{'order_files_path'}"); chmod(0777,"$cwd$cf{'user_carts_path'}"); } # ------------------------------------------------------------------- sub require_supporting_libraries { # require_supporting_libraries is used to read in some of # the supporting files that this script may take # advantage of, like add-ins. # # The incoming file and line arguments are split into # the local variables $file and $line while the file list # is assigned to the local list array @require_files. my($file, $line, @require_files) = @_; my($require_file); if($debug){ print "require_supporting_libraries: @require_files\n"; } # Next, the script checks to see if every file in the # @require_files list array exists (-e) and is readable by # it (-r). If so, the script goes ahead and requires it. foreach $require_file (@require_files) { if((-e "$require_file") && (-r "$require_file")) { my($fRequire) = "require \$require_file\;"; unless(eval($fRequire)){ print "Supporting Library File Error \n"; print "The program could not load the following supporting library:\n"; print "
$require_file\n"; print "for the following reason:\n"; print "
$@\n"; print ""; exit; } } # If not, the scripts sends back an error message that # will help the admin isolate the problem with the script. else { &file_error("Require Supporting Libraries: $require_file", $!, $file, $line); exit; } } # End of foreach $require_file (@require_files) } # End of sub require_supporting_libraries # ------------------------------------------------------------------- # Read and Parse Form Data # read_and_parse_form_data is a short subroutine # responsible to parse the incoming form data. sub read_and_parse_form_data { if($debug){ print "read_and_parse_form_data\n"; } my($postVars); my($meth) = $ENV{'REQUEST_METHOD'}; my($buffer); if (($meth eq '')||($meth eq 'GET')) { $buffer = $ENV{'QUERY_STRING'}; } else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } my(@pairs) = split(/[&;]/, $buffer); my($oNumber); my($oPID); my($sCount) = 1; foreach my $pair (@pairs) { my($name, $value) = split(/=/, $pair); $name =~ tr/+/ /; # Remove Binary Carriage Returns/Line feeds $name =~ s/%0D%0A//g; # Strip extra spaces while($name =~ /\s{2}/g){ $name =~ s/\s{2}/ /g; } $value =~ tr/+/ /; # Remove Binary Carriage Returns/Line feeds $value =~ s/%0D%0A//g; # Strip extra spaces while($value =~ /\s{2}/g){ $value =~ s/\s{2}/ /g; } $name =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge; $value =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge; if($name eq "version"){$value = "yes"} if(($value =~ /^%%(.*)%%$/g)|| ($value =~ /^%25%25(.*)%25%25$/g)){ undef $value; } # Select Multiple Option Modification if($name =~ /^OPTION\|(.*)\|(.*)/i){ if(($1 eq $oNumber)&&($2 eq $oPID)){ $name = "OPTION|$oNumber\.$sCount|$oPID"; $sCount++; } else{ $oNumber = $1; $oPID = $2; $sCount = 1; } } $form_data{$name} = $value; if($postVars eq ""){ $postVars .= "$name=$value"; } else{ $postVars .= ",$name=$value"; } } $ENV{'POST_VARS'} = $postVars; return %form_data; } # ------------------------------------------------------------------- sub error_check_form_data { my($pageToCheck) = @_; my($valid_page) = 0; my($extFound) = 0; if(($pageToCheck eq "")&&($form_data{'page'} ne "")){ $pageToCheck = $form_data{'page'}; } if($pageToCheck eq ""){ return 1; } # get rid of attempts to insert illegal characters $pageToCheck =~ s/[\&\`\;\*\|\^\!\(\)\{\}\<\>\n\l\r\\]//gs; # Check for only "/" and word characters. # disallow "../" if(($pageToCheck =~ /^[\w\/\._-]+$/)&&($pageToCheck !~ /\.{2}\//g)){ $valid_page = 1; } if($valid_page){ # Get a list of acceptable_filenames # used in any version of InfoDB my(@acceptable_files) = split(/\,/,$cf{'acceptable_filenames'}); my($file_extension); foreach $file_extension (@acceptable_files){ if($pageToCheck =~ /\.$file_extension$/i){ $extFound = 1; last; } } unless($extFound){ $valid_page = 0; } } unless($valid_page){ print "Access Denied! \n"; print "\n"; print "Cannot Open: $pageToCheck
"; print "This is an illegal filename..."; print "You can't use virtual paths or spaces in the filenames.
\n"; print "\n"; &update_error_log("PAGE LOAD WARNING", __FILE__, __LINE__); exit; } } # End sub error_check_form_data #-------------------------------------------------------------------- # HTML DISPLAY FUNCTIONS #-------------------------------------------------------------------- # Output Store Front Page # output_frontpage is used to display the store front page. sub output_frontpage { &redirect_user("$cf{'web_site_url'}/$cf{'store_front_page'}","0",""); } #-------------------------------------------------------------------- # Redirect Subroutine sub redirect_user { my($page,$quantity,$product) = @_; my($redir_file) = "$cwd/$cf{'templates_path'}/redirect.html"; my($line ); my($message); my($waitTime) = 0; if($page eq ""){ $page = $form_data{'page'}; } if($quantity > 1){ $product .= "s"; } if($product ne ""){ $message = $strings{'item_ordered_message'}; $message =~ s/%%qty%%/$quantity/ig; $message =~ s/%%product%%/$product/ig; } else{ $message = $strings{'one_moment_message'}; } open (REDIR, "<$redir_file") || &file_error("Cannot read the Redirect Page: $redir_file", $!,__FILE__,__LINE__); while ($line =){ $line =~ s/%25/%/g; $line =~ s/%%cart_id%%/$cart_id/ig; $line =~ s/%%web_site_url%%/$cf{'web_site_url'}/g; $line =~ s/%%secure_page_url%%/$secure_page_url/g; $line =~ s/%%page%%/$page/i; $line =~ s/%%message%%/$message/i; print $line; } close (REDIR); exit; } # ------------------------------------------------------------------- sub display_page { my($page,$selectBox) = @_; if($debug){ print "display_page: $page\n"; } my(@tempPage); open(PAGE, "<$page") || &file_error("Cannot read page: $page", $!,__FILE__,__LINE__); @tempPage = ( ); close(PAGE); my(@product_page) = &clean_up_page(@tempPage); undef @tempPage; my($displayPage) = join(" ",@product_page); undef @product_page; $displayPage =~ s//$selectBox/ig; print $displayPage; } # End of display_shipping_page #-------------------------------------------------------------------- # Display Products for Sale # display_products_for_sale is used to show the "product pages" # for the client to browse through. # # If the store is an HTML-based store, this routine will either # display the requested page or, in the case of a search, # perform a search on all the pages in the store for the # submitted keyword. # # If this is a database-based store, the script will use the # create_html_page_from_db to output the product page requested # or to perform the search on the database. sub display_products_for_sale { if($debug){ print "display_products_for_sale \n"; } # The script first determines which type of store this is. # If the store is HTML-based it simply displays the page as # requested with redirect_user. # # If the store_type is not set to HTML, it means that the # script must generate HTML product pages on the fly using # the database. if($store_type =~ /html/i){ &redirect_user("$cf{'web_site_url'}/$form_data{'page'}","0",""); } else{ &create_html_page_from_db; } } # create_html_page_from_db Subroutine ------------------------------- # create_html_page_from_db is used to genererate the # navigational interface for database-base stores. sub create_html_page_from_db { if($debug){ print "create_html_page_from_db \n"; } my($quantity,$product) = @_; # First, the script defines a few working variables which # will remain local to this subroutine. local(@database_rows, @database_fields, @item_ids, @display_fields); local($total_row_count, $id_index, $display_index); local($row, $field, $empty, $option_tag, $option_location, $output); # Next the script checks to see if there is actually a # page which must be displayed. if($page ne "" && $search_request eq "" && $continue_shopping eq "" && $previous_products eq "" && $next_products eq "") { &redirect_user("$cf{'web_site_url'}/$page","0",""); exit; } # Next the database is querried for rows containing the # value of the incoming product variable. The script uses # the submit_query subroutine in db_lib.pl passing to it # a reference to the list array database_rows. if(! exists $form_data{'hits_seen'}){ $form_data{'hits_seen'} = ""; } # We also want to keep track of the number of hits # seen so we can send the user back to the right page. my($previous_hits); if((defined $previous_products)&&($previous_products ne "")){ if(defined $form_data{'hits_seen'}){ $previous_hits = $form_data{'hits_seen'}; $form_data{'hits_seen'} = ($previous_hits - $cf{'max_db_rows_returned'}); } else{ $form_data{'hits_seen'} = ($cf{'max_db_rows_returned'}); } } my($next_hits); if (defined $next_products){ if((defined $form_data{'hits_seen'})&&($form_data{'hits_seen'} =~ /\d/)){ $next_hits = $form_data{'hits_seen'}; $form_data{'hits_seen'} = ($next_hits + $cf{'max_db_rows_returned'}); } else{ $form_data{'hits_seen'} = ($cf{'max_db_rows_returned'}); } } my($detailHits) = $form_data{'hits_seen'} || ""; if(defined $form_data{'detail'}){ $detailHits = 0; } ($status,$total_row_count,$total_records) = &submit_query(*database_rows, $detailHits); if((defined $form_data{'hits_seen'})&&($form_data{'hits_seen'} =~ /\d/)){ $hits_seen = $form_data{'hits_seen'} + $cf{'max_db_rows_returned'}; } else{ $hits_seen = $cf{'max_db_rows_returned'}; } if($total_row_count == 0){ my($Keywords) = $form_data{'keywords'}; my($category) = $form_data{'category'}; my($manufacturer) = $form_data{'manufacturer'}; my($error_title); my($error_message); if((defined $category) && (! defined $manufacturer)) { $error_message = "$strings{'no_products_found'} $category"; } elsif((defined $manufacturer) && (! defined $category)) { $error_message = "$strings{'no_manufacturer_found'} $manufacturer"; } elsif(defined $Keywords) { $error_message = "$strings{'no_keywords_found'} $Keywords"; } else { $error_message = &print_string("no_category_or_keyword"); } $error_title = $error_message; &bad_order_note($error_title,$error_message); exit; } if($database_rows[0] eq ""){ $total_row_count = ($total_row_count - 1); $total_records = ($total_records -1); } $start_row = ($form_data{'hits_seen'} + 1) || 1; # Now that the script has the database rows to be # displayed, it will display them. #----------------------------------------------------------------------------- # Call Product Template library functions my($db_index_of_product_id) = $cf{'db_index_of_product_id'}; my($db_index_of_price) = $cf{'db_index_of_price'}; my($db_index_of_name) = $cf{'db_index_of_name'}; my($db_index_of_link_label) = $cf{'db_index_of_link_label'}; my($db_index_of_page_link) = $cf{'db_index_of_page_link'}; my(%db_index_defining_item_id) = &read_config_file($config_file, "associative", "ITEM_ID_DEFINITION"); my(%db_fields) = &read_config_file($config_file, "associative", "DATABASE_FIELDS"); # Get the template page: my($dbTemplate) = &get_product_page_template; my($header,$body) = split(//,$dbTemplate); my($rowTemplate,$footer) = split(//,$body); undef $body; # First The page header. print &display_product_page_header($header,$quantity,$product); undef $header; # Now we can read in the database rows. $row_counter = 1; #### Across mod #### $row_count = 0; #### Across mod #### $TheEnd = "no"; #### Across mod #### foreach $row (@database_rows){ if($row eq ""){ next; } my($tempRowTemplate) = $rowTemplate; my(@database_fields) = (); @database_fields = split(/\|/, $row); if(($database_fields[$cf{'user_1'}] =~ /sold out/i)&& (!($cf{'use_inventory_control'} eq "yes"))){next;} $row_count++; #### Across mod #### foreach $field (@database_fields){ $field =~ s/\^/\|/g; $field =~ s/^NA$/$strings{'blank_field_character'}/g; $field =~ s/cart_id=/cart_id=$cart_id/g; # For every field in every database row, check # for option flags(%%OPTION%%). if ($field =~ /^%%OPTION%%/) { ($empty, $option_tag, $option_location) = split (/%%/, $field); $field = ""; my($oPage) = "$cwd$cf{'options_path'}/$option_location"; open(OPTION_FILE,"$oPage")|| &file_error ("Cannot read option file: $oPage", $!,__FILE__,__LINE__); while ( ) { s/%%PRODUCT_ID%%/$database_fields[$db_index_of_product_id]/g; $field .= $_; } close (OPTION_FILE); } } # Set the item-id my(@item_ids) = (); foreach $id_index (sort(keys(%db_index_defining_item_id))){ my($idIndex) = $db_index_defining_item_id{$id_index}; $database_fields[$idIndex] =~ s/cart_id=/cart_id=$cart_id/g; $database_fields[$idIndex] =~ s/^NA$/$strings{'blank_field_character'}/g; if($database_fields[$idIndex] eq ""){ $database_fields[$idIndex] = "-"; } push(@item_ids, $database_fields[$idIndex]); } my($defined_id) = join("\|",@item_ids); undef(@item_ids); $tempRowTemplate =~ s/PRODUCT_ITEM_ID/$defined_id/i; undef($defined_id); # Finally, the product display row is created with the two # arrays and sent to the product page template for display. #### Across mod #### if($detailHits ne ""){ $checkcounter = ($row_count + $detailHits); } else{ $checkcounter = $row_count; } if($checkcounter eq $total_records){ $TheEnd = "yes"; } $reset = ""; $reset = &display_product_page_row($tempRowTemplate, $row_counter, $TheEnd, \%db_fields, @database_fields); if($reset eq "yes"){ $row_counter = 1; } else{ $row_counter++; } # Inventory record count adjustment if($cf{'use_inventory_control'} eq "yes"){ my($inventoryFld) = $database_fields[$cf{'db_available_qty_field_number'}]; ($total_row_count,$total_records) = &modify_row_count_and_total_records($inventoryFld, $total_row_count, $total_records); } } # End of foreach $row (@database_rows) my($previous_next_links) = &createPreviousNextLinks($total_row_count, $hits_seen, $total_records, $cf{'max_db_rows_returned'}); $footer =~ s//$previous_next_links/ig; print &display_product_page_footer($footer,$total_row_count); exit; } # ------------------------------------------------------------------- sub display_product_page_header { my($header,$quantity,$product) = @_; if(defined $add_to_cart && $cf{'let_client_know_item_added'} eq "yes"){ my($order_message) = $strings{'item_ordered_message'}; $order_message =~ s/%%qty%%/$quantity/ig; $order_message =~ s/%%product%%/$product/ig; $header =~ s//$order_message/i; } if(defined $format_category){ my($catPage) = "$cf{'web_server_document_root'}/$format_category\.html"; if(-e "$catPage"){ open (FILE, "$catPage"); while ($line = ) { $ssi .= $line; } close FILE; $header =~ s//$ssi/g; } } # Other things to substitute: if(defined $category){ $header =~ s/CATEGORY/$category/g; } $header =~ s/ORDER_NUMBER/$order_number/g; return $header; } # ------------------------------------------------------------------- sub display_product_page_row { my($dbRowTemplate, $row_counter, $TheEnd, $refDisplayFields, @database_fields) = @_; my($columncount) = $cf{'number_of_columns'}; local(%db_fields); my($displayField); foreach $displayField (keys(%{$refDisplayFields})){ $db_fields{$displayField} = %{$refDisplayFields}->{$displayField}; } my($imageURL); my($detail) = $form_data{'detail'} || ""; if(($cf{'link_from_image_to_product_detail'} eq "yes")&&($detail eq "")){ $imageURL = &format_image_link_url(@database_fields); } else{ $imageURL = &format_image_url(@database_fields); } $dbRowTemplate =~ s/PRODUCT_IMAGE_URL/$imageURL/i; # Custom code Lysp Ltd (20/5/01) my($fullimageURL); my($smallimageURL); $fullimageURL = &format_image_fullurl(@database_fields); $dbRowTemplate =~ s/FULLSIZE/$fullimageURL/i; $smallimageURL = &format_image_smallurl(@database_fields); $dbRowTemplate =~ s/SMALLSIZE/$smallimageURL/i; # Inventory control my($inventory_fld); if($cf{'use_inventory_control'} eq "yes"){ $inventory_fld = $database_fields[$cf{'db_available_qty_field_number'}]; &format_inventory_field_for_display(\@database_fields,$inventory_fld); } # Display the price correctly my($the_price) = $database_fields[$cf{'db_index_of_price'}]; if($cf{'use_quantity_based_pricing'} =~ /yes/i){ $the_price = &get_quantity_based_price(\@database_fields,1,0); } if($the_price > 0){ $database_fields[$cf{'db_index_of_price'}] = &display_price($the_price); } else{ $database_fields[$cf{'db_index_of_price'}] = ""; } # Set the page link my($product_page_link) = &format_page_link($database_fields[$cf{'db_index_of_page_link'}], $database_fields[$cf{'db_index_of_link_label'}]); if($product_page_link =~ /page=$strings{'blank_field_character'}/i){ $database_fields[$cf{'db_index_of_page_link'}] = ""; } # SSI for a PRODUCT_ID.html page. my($pid) = $database_fields[$cf{'db_index_of_product_id'}]; my($ssi); my($line); my($pidPage) = "$cf{'web_server_document_root'}/$pid\.html"; if(-e "$pidPage"){ open (FILE, "$pidPage"); while(defined($line = )) { $ssi .= $line; } close FILE; $dbRowTemplate =~ s//$ssi/g; } # substitute the fields in the database rows my($key); foreach $key (keys(%db_fields)){ if($db_fields{$key} eq "yes"){next;} if($database_fields[$db_fields{$key}] =~ /^$strings{'blank_field_character'}$/){ $dbRowTemplate =~ s/%%$key%%//ig; $dbRowTemplate =~ s/$key//ig; } else { $dbRowTemplate =~ s/%%$key%%/$database_fields[$db_fields{$key}]/ig; $dbRowTemplate =~ s/$key/$database_fields[$db_fields{$key}]/ig; } } $dbRowTemplate =~ s/PRODUCT_PAGE_LINK/$product_page_link/i; $dbRowTemplate =~ s/PAGE_LINK/$product_page_link/i; #print "row_counter: $row_counter
\n"; #print "column_counter: $columncount
\n"; #print "The End: $TheEnd
\n"; my($printFlag) = 0; if($columncount > 1){ if(($row_counter < $columncount)&&($TheEnd ne "yes")) { $finalrow .= $dbRowTemplate; $reset = "no"; } if(($row_counter == $columncount)&&($TheEnd ne "yes")) { $finalrow .= $dbRowTemplate . ""; $printFlag = 1; $reset = "yes"; } if(($row_counter <= $columncount)&&($TheEnd eq "yes")) { $finalrow .= $dbRowTemplate; $printFlag = 1; } } else{ $finalrow = $dbRowTemplate; $printFlag = 1; } # CUSTOM ALTERNATE COLOR my($oddEven) = ($row_counter / 2) - int($row_counter / 2); if($oddEven > 0){ $finalrow =~ s/ / /ig; } else{ $finalrow =~ s/ / /ig; } # Print if required first checking the inventory control if(($printFlag == 1)&&($cf{'use_inventory_control'} eq "yes")&& (&display_inventory_row($inventory_fld) == 1)){ print $finalrow; } elsif(($printFlag == 1)&&($cf{'use_inventory_control'} !~ /yes/i)){ print $finalrow; } if($reset eq "yes"){ undef $finalrow; } return $reset; } # ------------------------------------------------------------------- sub display_product_page_footer { my($footer,$total_row_count) = @_; if($footer =~ //i) { if($total_row_count <= $cf{'max_db_rows_returned'}) { $footer =~ s///ig; } } if($footer =~ //i) { if($hits_seen >= $total_records) { $footer =~ s///ig; } } return $footer; } # ------------------------------------------------------------------- sub get_product_page_template { my($product_row_template_path); $product_row_template_path = "$cwd$cf{'templates_path'}/$cf{'product_page_template'}"; my($detail) = $form_data{'detail'} || ""; my($template) = $form_data{'template'} || ""; if($detail ne ""){ $product_row_template_path = "$cwd$cf{'templates_path'}/$cf{'product_page_detail'}"; } if(($template ne "")&&($detail eq "")){ my($tPage) = "$form_data{'template'}.html"; &error_check_form_data($tPage); $product_row_template_path = "$cwd$cf{'templates_path'}/$tPage"; } print "get_product_page_template: " . $product_row_template_path if $debug; my($TempFile); open(PRODUCT_PAGE_TEMPLATE, "<$product_row_template_path") || &file_error("Cannot read template page: $product_row_template_path", $!,__FILE__,__LINE__); undef $/; $TempFile = ; # read in whole file $/ = "\n"; # back to normal input delim close(PRODUCT_PAGE_TEMPLATE); my(@product_page) = (); @product_page = &clean_up_page(split(/\n/,$TempFile)); undef $TempFile; my($db_template) = join("\n",@product_page); undef @product_page; return $db_template; } # ------------------------------------------------------------------- sub split_out_images { my($imageField) = @_; my(@images) = (); my($img); my(@splitimages); my($fullsize); my($thumbnail); @images = split(/\>\; # read in whole file $/ = "\n"; # back to normal input delim close(ERROR_PAGE_TEMPLATE); $TempFile =~ s/%%script_url%%/$script_url/ig; $TempFile =~ s//$hidden_fields/ig; $TempFile =~ s/%%web_site_url%%/$cf{'web_site_url'}/ig; $TempFile =~ s/%%secure_page_url%%/$secure_page_url/ig; $TempFile =~ s/%%home_page%%/$cf{'store_front_page'}/ig; $TempFile =~ s/%%main_page%%/$cf{'store_main_page'}/ig; $TempFile =~ s/%%page%%/$form_data{'page'}/ig; $TempFile =~ s//$error_title/i; $TempFile =~ s//$error_message/i; my(@tFile) = split(/\n/,$TempFile); $TempFile = ""; foreach my $line (@tFile){ if($line =~ //ig){ my($ssiPage) = &ssi_include($line); $line =~ s//$ssiPage/ig; } $TempFile .= "$line\n"; } print $TempFile; exit; } # make_hidden_fields Subroutine ------------------------------------- # make_hidden_fields is used to generate the hidden fields # necessary for maintaining state. sub make_hidden_fields { if($debug){ print "make_hidden_fields \n"; } my($hidden); my($db_query_row); my($db_form_field); # Reset the hit_seen if needed if((defined $form_data{'hits_seen'})&& ($form_data{'hits_seen'} eq 0)){ $form_data{'hits_seen'} = ""; } # $hidden is defined initially as containing the cart_id # and page hidden tags which are necessry state variables # on EVERY page in the cart. my(@hiddenFields) =("cart_id", "store_type", "page", "search", "subtotal", "and", "total_quantity", "case_sensitive", "exact_match", "affiliate_id", "store", "hits_seen", "template", "database"); my($field); foreach $field (@hiddenFields){ if((defined $form_data{$field})&&($form_data{$field} ne "")){ $hidden .= "\n"; } } foreach $db_query_row (@db_query_criteria) { $db_form_field = (split(/\|/,$db_query_row))[0]; #if(defined $form_data{$db_form_field} && $db_form_field ne "keywords"){ if((defined $form_data{"detail"})&&($form_data{"detail"} ne "") &&($db_form_field eq "product")){next;} if((defined $form_data{$db_form_field})&&($form_data{$db_form_field} ne "")){ $hidden .= qq~\n~; } } return ($hidden); } # End of make_hidden_fields # ------------------------------------------------------------------- # CART FUNCTIONS # ------------------------------------------------------------------- sub get_cart_id_from_address_log { if($debug){ print "get_cart_id_from_address_log\n"; } # If the incoming cart_id is empty, we first check to # see if we have already assigned and written one to # the users ip_address.log file. If not, then we # assign a new number and put it into an ip_address.log # file to later reference it while the user moves # throughout the site. if((!(defined $cart_id))||($cart_id eq "")){ $ip_log = "$user_carts_path/ip\.$remote_host"; if(-e "$ip_log"){ open (ADDRESS_LOG,"$ip_log"); @cart_number = ( ); close (ADDRESS_LOG); } if(defined $cart_number[0]){ $cart_id = $cart_number[0]; $form_data{'cart_id'} = $cart_id; $users_cart_path = "$cwd$cf{'user_carts_path'}/$cart_id.cart"; } else{ $cart_id = ""; $cart_id = &assign_a_unique_shopping_cart_id; } } #End of if cart id = is blank else{ $cart_id = ""; $cart_id = &assign_a_unique_shopping_cart_id; } $cart_id =~ s/\s//; return $cart_id, $ip_log; } # end get_cart_id_from_address_log # ------------------------------------------------------------------- sub delete_old_carts { if($debug){ print "delete_old_carts \n"; } # The subroutine gets a list of all of the shoppping cart # and IP address files in the user_carts directory and # deletes them if they are older than 1 hour. # ----- Delete Old User Cart files ---------------------------------- $user_carts_path = "$cwd$cf{'user_carts_path'}"; opendir (USER_CARTS, "$user_carts_path") || &file_error("Cannot delete old carts: $user_carts_path", $!,__FILE__, __LINE__); @carts = grep(/\.cart/,readdir(USER_CARTS)); closedir (USER_CARTS); foreach $cart (@carts) { if (-M "$user_carts_path/$cart" > $cf{'number_of_days_to_keep_old_carts'}) { unlink("$user_carts_path/$cart"); } } # ----- Delete Old User IP Address files ---------------------------- opendir (USER_ADDRESS_FILES, "$user_carts_path") || &file_error("Cannot delete old ip address files: $user_carts_path", $!,__FILE__,__LINE__); @user_addresses = grep(/\d$/,readdir(USER_ADDRESS_FILES)); closedir (USER_ADDRESS_FILES); foreach $address (@user_addresses) { if (-M "$user_carts_path/$address" > $cf{'number_of_days_to_keep_old_carts'}) { unlink("$user_carts_path/$address"); } } } # End of sub delete_old_carts # ------------------------------------------------------------------- sub assign_a_unique_shopping_cart_id { if($debug){ print "assign_a_unique_shopping_cart_id \n"; } # assign_a_unique_shopping_cart_id is a subroutine used to # assign a unique cart id to every new client. local(%access_array); local($access_log_name); # Get the access log filepath if ($cf{'log_accesses'} eq "yes") { $access_log_name = $cf{'access_log_file_name'}; $access_log_path = "$cwd$cf{'log_files_path'}/$access_log_name"; if(!(-e "$access_log_path")) { local($path) = "$cwd$cf{'log_files_path'}"; chmod(0777,$path); open (ACCESS_LOG, ">$access_log_path")|| &file_error("Cannot create access log file: $access_log_path", $!,__FILE__,__LINE__); print ACCESS_LOG "DATE | SERVER_NAME | IP_ADDR | HOST_IP | SCRIPT_NAME | QUERY_STRING\n"; close (ACCESS_LOG); chmod(0777,$access_log_path); } &get_file_lock("$access_log_path.lockfile"); open (ACCESS_LOG, ">>$access_log_path")|| &file_error("Cannot append to access log file: $access_log_path", $!,__FILE__,__LINE__); # Using the keys function, the script grabs all the # keys of the %ENV associative array. $new_access = "$date\|"; $new_access .= "$ENV{'SERVER_NAME'}\|"; $new_access .= "$ENV{'REMOTE_ADDR'}\|"; $new_access .= "$ENV{'REMOTE_HOST'}\|"; $new_access .= "$ENV{'SCRIPT_NAME'}\|"; $new_access .= "$ENV{'QUERY_STRING'}\|"; # The script then takes off the final pipe, adds the new # access to the log file, closes the log file and removes # the lock file. chop $new_access; print ACCESS_LOG "$new_access\n"; close (ACCESS_LOG); &release_file_lock("$access_log_path.lockfile"); } # Now that the new access is recorded, the script assigns # the user their own unique shopping cart. if($cf{'use_cookies'} ne "yes"){ if($remote_host ne ""){ $ip_address_file = "ip.$remote_host"; } else { my $ip_address_error_title = $strings{'ip_address_error_message'} &print_error_messages($ip_address_error_title,"ip_address_error"); &update_error_log("COULD NOT READ USERS IP ADDRESS", __FILE__,__LINE__); exit; } } $cart_id = ""; srand (time|$$); $cart_id = int(rand(91919191)); $users_cart_path = "$cwd$cf{'user_carts_path'}/$cart_id.cart"; # We check the list of carts to make sure that # there is not one with the same value. $cart_count = 0; while(-e "$users_cart_path"){ if($cart_count == 7){ my $random_title = $strings{'randomize_error_message'}; &print_error_messages($random_title,"randomize_error_message"); &update_error_log("COULD NOT CREATE UNIQUE CART ID", __FILE__,__LINE__); exit; } srand (time|$$); $cart_id = int(rand(91919191)); $cart_count++; } # End of while (-e $users_cart_path) # Now print the users cart id into the address log. if($cf{'use_cookies'} ne "yes"){ open (ADDRESS_LOG, ">$user_carts_path/$ip_address_file")|| &file_error("Cannot write cart_id to ip address file: $user_carts_path/$ip_address_file", $!,__FILE__, __LINE__); print ADDRESS_LOG "$cart_id"; close (ADDRESS_LOG); chmod(0775,"$user_carts_path/$ip_address_file"); } $form_data{'cart_id'} = $cart_id; # If there is a problem opening the new cart, we'll output # an error message. $users_cart_path = "$cwd$cf{'user_carts_path'}/$cart_id.cart"; open (CART, ">$users_cart_path") || &file_error("Cannot create user cart file: $users_cart_path", $!,__FILE__,__LINE__); close(CART); chmod(0777,$users_cart_path); return $cart_id; } # ------------------------------------------------------------------- # Add to Shopping Cart # The add_to_the_cart subroutine is used to add items to # the customer's unique cart. sub add_to_the_cart { if($debug){ print "add_to_the_cart \n"; } local($add_item) = "no"; my($item_price) = 0; # The script must first figure out what the client has # ordered. # # It begins by using the %form_data associative array # given to it by cgi-lib.pl. It takes all of the keys # of the form_data associative array and drops them into # the @items_ordered array. @items_ordered = keys (%form_data); # Next it begins going through the list of items ordered # one by one. foreach $item (@items_ordered) { # There are some incoming items that don't need to be # processed. Specifically, we do not care about cart_id, # page, keywords, add_to_cart, or whatever incoming # administrative variables exist because these are all # values set internally by this script. All incoming items # are prefixed with the tag "item-". When the script sees # this tag, it knows that it is seeing an item to be added # to the cart. # # Similarly, items which are actually options info are # denoted with the "option" keyword. We will also accept # those for further processing. if (($item =~ /^item-/i || $item =~ /^option/i) && $form_data{$item} ne "") { # Inventory Control if(($cf{'use_inventory_control'} eq "yes")&& ($form_data{$item} > 0)){ &verify_inventory_quantity_on_add_to_cart($item,$form_data{$item}); } # If $item begins with the keyword "option", which we set # specifically in the HTML file, the script will add # (push) that item to the array called @options. However, # before we make the check, we must strip the "item-" # keyword off the item so that we have the actual row # number for comparison. $item =~ s/^item-//i; if ($item =~ /^option/i) { push (@options, $item); } # On the other hand, if it is not an option, the script adds # it to the array @items_ordered_with_options, but adds # both the item and its value as a single array element. # # The resulting string would be something like the following: # 2|0001|2.98|Product Name # qty.|item number|price|product name # # Finally, the script will dissallow any non-digit characters # or zero values ($form_data{$item} == 0). In both cases the # client will be sent to the subroutine bad_order_note located # in html_lib.pl. else { if(($form_data{"item-$item"} =~ /\D/)||($form_data{"item-$item"} == 0)) {next;} else { $add_item = "yes"; $quantity = $form_data{"item-$item"}; push (@items_ordered_with_options, "$quantity\|$item\|"); } } } # End of if ($item ne "$variable" && $form_data{$item} ne "") } #End of foreach $item (@items_ordered) if($add_item eq "no"){ my($error_title) = $strings{'bad_quantity_title'}; my($error_message) = &print_string("bad_quantity_change"); &bad_order_note($error_title,$error_message); exit; } # Now the script goes through the array @items_ordered_with_options # one item at a time in order to modify any item which has had # options applied to it. foreach $item_ordered_with_options (@items_ordered_with_options) { # First, clear out a few variables that we are going to # use for each item. # # $options will be used to keep track of all of the # options selected for any given item. # # $option_subtotal will be used to determine the total # cost of each option. # # $option_grand_total will be used to calculate the # total cost of all ordered options. # # $item_grand_total will be used to calculate the total # cost of the item ordered factoring in quantity and # options. $options = ""; $option_subtotal = 0; $option_grand_total = 0; $item_grand_total = 0; # Now split out the $item_ordered_with_options into it's # fields. Note that we have defined the index location of # some important fields in InfoDB.cfg file. $item_ordered_with_options =~ s/~qq~/\"/g; $item_ordered_with_options =~ s/~gt~/\>/g; $item_ordered_with_options =~ s/~lt~/\"; } else { if($option_price eq "0.00"){ $options .= "$option_name,
"; } else{ $options .= "$option_name $option_price,
"; } } #--------------------------------------------------------------------- if((defined $option_weight)&&($option_weight > 0)) { $cart_row[$cf{'cart_index_of_weight'}] = $option_weight; } #--------------------------------------------------------------------- # The script must also calculate the cost changes with # options. To do so, it will take the current value of # $option_grand_total and add to it the value of the # current option. $unformatted_option_grand_total = $option_grand_total + $option_price; $option_grand_total = &format_price($unformatted_option_grand_total); } # End of if ($option_item_number eq "$item_id_number") } # End of foreach $option (@options) # Next, the script takes off the last comma in options. #chop $options; # Now, the script adds a space after each comma so the # display looks nicer. $options =~ s/,/, /g; $options =~ s/,
$//; # Next, the counter subroutine will add an $item_number # which the script can use to identify the shopping cart # item row. $counter_file_path = "$cwd$cf{'log_files_path'}/counter.file"; chmod(0777,$counter_file_path); $item_number = &counter ($counter_file_path, __FILE__, __LINE__); # Finally, the script makes the last price calculations # and appends every ordered item to $cart_row and also # take out the commas in the thousands and up prices. $item_price =~ s/,//g; $unformatted_item_grand_total = $item_price + $option_grand_total; $item_grand_total = &format_price("$unformatted_item_grand_total"); foreach $field (@cart_row) { $cart_row .= "$field\|"; } $cart_row .= "$options\|$item_grand_total\|$item_number\n"; } # End of foreach $item_ordered_with_options..... # When it is done appending all the items to $cart_row, # the script opens the user's shopping cart and adds the # new items. open (CART, ">>$users_cart_path") || &file_error("Cannot add to user cart file: $users_cart_path", $!,__FILE__,__LINE__); print CART "$cart_row"; close (CART); # Then, the script sends the client back to a previous # page or to the display cart page. if ($store_type =~ /html/i) { if ($cf{'display_cart_after_purchase'} eq "yes") { &display_cart_contents; } else { &redirect_user("$cf{'web_site_url'}/$page",$quantity,$item_name); exit; } } else { if ($cf{'display_cart_after_purchase'} eq "yes") { &display_cart_contents; } elsif ($are_any_query_fields_filled_in eq "yes") { $page = ""; &create_html_page_from_db($quantity,$item_name); } else { &create_html_page_from_db($quantity,$item_name); } } } #-------------------------------------------------------------------- # Modify Quantity of Items in the Cart # The modify_quantity_of_items_in_cart subroutine is # responsible for making quantity modifications in the # customer's cart. It takes no arguments and as called # with the following syntax: sub modify_quantity_of_items_in_cart { if($debug){ print "modify_quantity_of_items_in_cart \n"; } local(@incoming_data) = keys(%form_data); local($key); foreach $key (@incoming_data){ if(($key =~ /[\d]/)&&($form_data{$key} =~ /\D/)){ my($error_title) = $strings{'bad_quantity_title'}; my($error_message) = &print_string("bad_quantity_change"); &bad_order_note($error_title,$error_message); exit; } unless(($key =~/[\D]/)&&($form_data{$key} =~ /[\D]/)) { if($key =~ /delete/){ my($deleteItem) = (split(/\_/,$key))[1]; $form_data{$deleteItem} = 0; } if ($form_data{$key} ne ""){ push (@modify_items, $key); } } } # End of foreach $key (@incoming_data) # Then, the script must open up the client's cart and go # through it line by line. open (CART, "<$users_cart_path") || &file_error("Cannot read user cart file: $users_cart_path", $!,__FILE__,__LINE__); # The script needs this number to check the current line # against the list of items to be modified. Recall that # this list will be made up of all the cart items which # are being modified. while () { @database_row = split (/\|/, $_); # Inventory Control if($cf{'use_inventory_control'} eq "yes"){ &verify_inventory_quantity_on_modify_cart(\@database_row); } $cart_row_number = pop (@database_row); push (@database_row, $cart_row_number); $old_quantity = shift (@database_row); chop $cart_row_number; # Next, the script checks to see if the item number # submitted as form data is equal to the number of the # current database row. foreach $item (@modify_items) { if(($item eq $cart_row_number)&&($form_data{$item} > 0)){ # If so, it means that the script must change the quantity # of this item. It will replace the old quantity with the # quantity submitted by the client ($form_data{$item}). $shopper_row .= "$form_data{$item}\|"; # Now the script adds the rest of the database row to # $shopper_row and sets two flag variables. foreach $field (@database_row){ # Quantity Based Pricing --------------------- if($cf{'use_quantity_based_pricing'} =~ /yes/i){ my($match) = $database_row[$cf{'price_after_options'} - 1]; print "Match: $match
\n" if $debug; if($field eq $match){ # Grab the option price my($totalPrice) = $database_row[$cf{'price_after_options'} - 1]; my($currentPrice) = &get_quantity_based_price(\@database_row,$old_quantity,1,0); my($optionPrice) = &format_price($totalPrice - $currentPrice); # Set the current price and # add the option price to it... my($item_price) = &get_quantity_based_price(\@database_row,$form_data{$item},1); $item_price += $optionPrice; print "Item Price: $item_price
\n" if $debug; $field = $item_price; } } $shopper_row .= "$field\|"; } $quantity_modified = "yes"; chop $shopper_row; } # End of if ($item eq $cart_row_number) elsif(($item eq $cart_row_number)&&($form_data{$item} == 0)){ $quantity_modified = "yes"; } } # End of foreach $item (@modify_items) # If the script gets this far and $quantity_modified has # not been set to "yes", it knows that the above routine # was skipped because and that the current row is not having its # quantity changed and can be added to $shopper_row as is. if ($quantity_modified ne "yes") { $shopper_row .= $_; } # Now the script clears out the quantity_modified variable # so that next time around it will have a fresh test. $quantity_modified = ""; } # End of while () close (CART); # Now, replace the old cart with the new information and # send the client back to the view cart screen. if($shopper_row eq ""){ delete($form_data{'submit_change'}); $form_data{'submit_delete'} = 1; } open (CART, ">$users_cart_path") || &file_error("Cannot modify quantity of items in the cart file: $users_cart_path", $!,__FILE__,__LINE__); print CART "$shopper_row"; close (CART); &display_cart_contents; } # End of if ($form_data{'submit_change_quantity'} ne "") #-------------------------------------------------------------------- # Delete Item From Cart # The job of delete_from_cart is to take a set of items # submitted by the user for deletion and actually delete # them from the customer's cart. sub delete_from_cart { if($debug){ print "delete_from_cart \n"; } # As with the modification routines, the script first # checks for valid entries. @incoming_data = values (%form_data); foreach $key (@incoming_data) { # We still want to make sure that the key is a cart row # number and that it has a value associated with it. # If it is actually an item which the user has asked to # delete, the script will add it to the delete_items array. if(defined $key){ unless ($key =~ /[\D]/) { if (defined $form_data{$key}) { push (@delete_items, $key); } } # End of unless ($key =~ /[\D]/... } } # End of foreach $key (@incoming_data) # Once the script has gone through all the incomming form # data and collected the list of all items to be deleted, # it opens up the cart and gets the $cart_row_number to # be deleted. open (CART, "<$users_cart_path") || &file_error("Cannot read user cart file: $users_cart_path", $!,__FILE__,__LINE__); while ( ) { @database_row = split (/\|/, $_); $cart_row_number = pop (@database_row); $db_id_number = pop (@database_row); push (@database_row, $db_id_number); push (@database_row, $cart_row_number); chop $cart_row_number; $old_quantity = shift (@database_row); # Unlike a modification, for deletion all we need to # do is check to see if the current database row matches # any submitted item for deletion. $delete_item = ""; foreach $item (@delete_items) { if ($item eq $cart_row_number) { $delete_item = "yes"; } } # End of foreach $item (@add_items) if ($delete_item ne "yes") { $shopper_row .= $_; } } # End of while ( ) close (CART); # Then, as it did for a modification, the scipt overwrites # the old cart with the new information and sends the client # back to the view cart page. open (CART, ">$users_cart_path") || &file_error("Cannot write user cart file: $users_cart_path", $!,__FILE__,__LINE__); print CART "$shopper_row"; close (CART); &display_cart_contents; } # End of if ($form_data{'submit_deletion'} ne "") #-------------------------------------------------------------------- # The job of display_cart_table is to display the current # contents of the user's cart using the cart page template. sub display_cart_contents { if($debug){ print "display_cart_contents \n"; } my($cart_page) = "$cwd$cf{'templates_path'}/$cf{'cart_page_template'}"; my(@cart_rows); # Next, the client's cart is read line by line # (file errors handled by file_error as usual). open (CART, "<$users_cart_path") || &file_error("Cannot read user cart file: $users_cart_path", $!,__FILE__,__LINE__); @cart_rows = ( ); close(CART); if(@cart_rows eq 0){ my($error_title); my($error_message); if(($submit_delete ne "")||($form_data{'submit_delete'} ne "")){ $error_title = $strings{'delete_all_title'}; $error_message = $strings{'deleted_all_items_message'}; } else{ $error_title = $strings{'no_items_in_cart_title'}; $error_message = $strings{'no_items_in_cart_message'}; } &bad_order_note($error_title,$error_message); exit; } if($cf{'sort_cart_rows'} eq "yes"){ @cart_rows = map { $_->[0] } sort { "\u$a->[1]" cmp "\u$b->[1]" } map { [ $_, (split /\|/,$_)[$cf{'cart_sort_field'}] ] } @cart_rows; } # Get the cart page template my($header,$rows,$footer) = &get_cart_template($cart_page); # the subroutine calls cart_table_header to # begin outputting the cart display template. %cart_row_fields = &read_config_file($config_file, "associative", "CART_FIELD_NUMBERS"); $header =~ s/CART_NUMBER/$cart_id/ig; print $header; # Now it outputs each row in the cart to the template my($subTotal) = 0; foreach my $line (@cart_rows){ my($row,$subtotal,$quantity) = &display_cart_rows($line,$rows,\%cart_row_fields,"no"); $subTotal += $subtotal; print $row; } # Display Product Specific Shipping Rates my($shipRate) = 0; my($gTotal) = 0; if($cf{'use_product_specific_shipping'} eq "yes"){ $shipRate = &calculate_shipping; $shipRate = &display_price($shipRate); $gTotal = &display_price($subTotal + $shipRate); } # and the cart template page footer $subTotal = &display_price($subTotal); $footer =~ s/SUBTOTAL/$subTotal/g; $footer =~ s/SHIPPING_COSTS/$shipRate/g; $footer =~ s/GRAND_TOTAL/$gTotal/g; print $footer; exit; } # End of sub display_cart_contents #----------------------------------------------------------------------------- # TEMPLATE FUNCTIONS #----------------------------------------------------------------------------- sub get_cart_template{ my($cart_page) = @_; print "Get cart template
\n" if $debug; # Read the template file my(@TempFile); open(PAGE_TEMPLATE,"<$cart_page")|| &file_error("Cannot read cart page template file: $cart_page", $!,__FILE__,__LINE__); @TempFile =; # read in whole file close(PAGE_TEMPLATE); my($sTempFile) = join(" ",&clean_up_page(@TempFile)); undef @TempFile; # Test for upper/lower case tags: my($cartRow); my($cartFooter); $sTempFile =~ s/tr name/TR NAME/ig; $cartRow = " "; $cartFooter = " "; my($header,$theRest) = split(/$cartRow/,$sTempFile); $theRest = $cartRow . $theRest; my($rows,$footer) = split(/$cartFooter/,$theRest); $footer = $cartFooter . $footer; return($header,$rows,$footer); } # ------------------------------------------------------------------- sub display_cart_rows { my($cart_row,$template,$refCartFields,$show_at_orderform) = @_; $cart_row =~ s/\n//g; my(@cart_fields) = split(/\|/,$cart_row); my($line); my($total_quantity) = 0; my($cart_row_number) = $cart_fields[$cf{'unique_cart_line_id'}]; # Clean up the blank fields foreach $line (@cart_fields){ if(($line =~ /^NA/i)&&(!($line =~ /NA./i))||($line eq "")){ $line =~ s/NA/$strings{'blank_field_character'}/i; if($line eq ""){ $line = $strings{'blank_field_character'}; } } } # Now, for each row in the cart, we substitute # the tag in the template file with the field from # the cart. my(%calcFields); my($delete_checkbox) = ""; $template =~ s/DELETE/$delete_checkbox/g; my($quantity) = $cart_fields[0]; if($show_at_orderform eq "yes"){ $calcFields{'quantity'} = $quantity; } else { $calcFields{'quantity'} = ""; } $calcFields{'product_price'} = &display_price($cart_fields[%{$refCartFields}->{'price_after_options'}]); my($price_after_options) = $cart_fields[%{$refCartFields}->{'price_after_options'}]; my($calulated_subtotal) = ($quantity * $price_after_options); $calcFields{'price_after_options'} = &display_price(($quantity * $price_after_options)); if($cf{'use_product_specific_shipping'} eq "yes"){ $cart_fields[$cf{'product_weight'}] =~ s/,/ /g; } my($key,$value); while(($key,$value)=each(%{$refCartFields})){ if(defined $calcFields{$key}){ $template =~ s/\U$key/$calcFields{$key}/g; } else{ $template =~ s/\U$key/$cart_fields[$value]/g; } } $total_quantity += $quantity; return ($template,$calulated_subtotal,$total_quantity); } # ------------------------------------------------------------------- sub get_cart_rows { my($template,$refCart,$atOrderForm) = @_; # Get cart rows is for the orderform, receipt, and email # but could be used for other pages. my($cartRows); my($header,$rows,$footer) = &get_cart_template($template); undef $header; undef $footer; # the subroutine calls cart_table_header to # begin outputting the cart display template. my(%cart_row_fields) = &read_config_file($config_file, "associative", "CART_FIELD_NUMBERS"); foreach my $line (@{$refCart}){ my($row,$subtotal,$quantity) = &display_cart_rows($line,$rows,\%cart_row_fields,$atOrderForm); while($row =~ /^\s/){ $row =~ s/^\s//; } $cartRows .= $row; } return $cartRows; } # --------------------------------------------------------------------- # CLEAN UP FROM PAGE EDITORS # --------------------------------------------------------------------- sub clean_up_page { if($debug){ print "clean_up_page
\n"; } my(@page_template) = @_; my($store) = $form_data{'store'}; my(%dataFields) = ( "%%cart_id%%", $cart_id, "%%and%%", $form_data{'and'}, "%%category%%", $format_category, "%%format_category%%", $format_category, "%%product%%", $form_data{'product'}, "cart_id=", "cart_id=$cart_id", "%%store%%", $store, "%%script_url%%", $script_url, "%%secure_script_url%%", $secure_script_url, "%%page%%", $form_data{'page'}, "RETURN_PAGE", $form_data{'page'}, "%%home_page%%", $cf{'store_front_page'}, "%%main_page%%", $cf{'store_main_page'}, "%%keywords%%", $form_data{'keywords'}, "%%manufacturer%%", $form_data{'manufacturer'}, "%%hits_seen%%", $form_data{'hits_seen'}, "%%secure_page_url%%", $secure_page_url, "%%web_site_url%%", $web_site_url, "STARTING_RECORD", $start_row, "ROW_COUNT", $total_row_count, "TOTAL_RECORDS", $total_records, "GRAPHICS_URL", $cf{'graphics_url'}, "CGIDIR", $cgidir, "", $date, "%%affiliate_id%%", $form_data{'affiliate_id'}, "REMOTE_HOST", $form_data{'user_host'}, "%%cart_quantity%%", $form_data{'cart_quantity'}, "%%cart_total%%", $form_data{'cart_total'}, "%%cart_weight%%", $form_data{'cart_weight'}); my($line); my($newLine); my(@new_template) = (); my($key); my($hidden_fields) = &make_hidden_fields; my($hidden_cart_fields); if($cf{'post_to_remote_server'} eq "yes"){ $hidden_cart_fields = &make_hidden_cart_fields; } foreach $line (@page_template){ $line =~ s/%25/%/ig; $line =~ s//$hidden_fields/ig; $line =~ s//$hidden_fields/ig; if((defined $hidden_cart_fields)&&($hidden_cart_fields ne "")){ $line =~ s//$hidden_cart_fields/ig; $line =~ s//$hidden_cart_fields/ig; } foreach $key (keys(%dataFields)){ my($value) = $dataFields{$key} || ""; $value =~ s/ /%20/g; $line =~ s/$key/$value/ig; } if($line =~ //ig){ my($ssiPage) = &ssi_include($line); $line =~ s//$ssiPage/ig; } if($line =~ //ig){ my($ssiPage) = &ssi_include($line); $line =~ s//$ssiPage/ig; } $newLine .= $line; push(@new_template,$newLine); $newLine = ""; } # end foreach line return(@new_template); } #-------------------------------------------------------------------- # MISC. SCRIPT UTILITY SUBROUTINES #-------------------------------------------------------------------- sub make_hidden_cart_fields { if($debug){ print "make_hidden_cart_fields\n"; } my(@cart_rows); my($hidden_cart_fields); my($row_counter) = 1; my($cart_line); open (CART, "<$users_cart_path") || &file_error("Cannot read user cart file: $users_cart_path", $!,__FILE__,__LINE__); @cart_rows = (); close(CART); if(@cart_rows > 0){ foreach $cart_line (@cart_rows){ chop $cart_line; $cart_line =~ s/\"/"/g; $hidden_cart_fields .= "\n"; $row_counter++; } } return($hidden_cart_fields); } # End sub make_hidden_cart_fields # ------------------------------------------------------------------- # counter is used to keep track of unique cart database id # numbers so that every item in every cart will be # uniquely identifiable. sub counter { if($debug){ print "Cart counter\n"; } # First, the subroutine assigns to the local variable # $counter_file, the filename that we passed to this # subroutine from the main script. local($counter_file, $file, $line) = @_; local ($item_number); # Next, the script checks to see if the counter file # exists. If it does not, then it attempts to create it. if (!(-e $counter_file)) { open(COUNTER_FILE, ">$counter_file")|| &file_error("Cannot create cart counter file: $counter_file", $!,__FILE__,__LINE__); print COUNTER_FILE "1\n"; close(COUNTER_FILE); } # Next, the script opens the counter file. If the # counter file cannot be opened, however, # &file_error is called as usual. open (COUNTER_FILE, "$counter_file")|| &file_error("Cannot read cart counter file: $counter_file", $!,__FILE__,__LINE__); # Then, the script checks to see what number the counter # is currently on and assign that value to $item_number. while ( ) { $item_number = "$_"; } close (COUNTER_FILE); # It then adds one to that number, changes the counter # file to reflect the incrementation, returns the number to # the main script, and closes the counter file. $item_number += 1; open (NOTE, ">$counter_file")|| &file_error("Cannot update cart counter file: $counter_file", $!,__FILE__,__LINE__); print NOTE "$item_number\n"; close (NOTE); return $item_number; } # End of sub counter # ------------------------------------------------------------------- sub update_error_log { if($debug){ print "update_error_log\n"; } # update_error_log is used to append to the error log if # there has been a problem executing this script and/or # email the store. # $type_of_error will be a text string explaining what # kind of error is being logged. local ($type_of_error, $file_name, $line_number) = @_; local ($log_entry, $email_body, $variable, @env_vars); local ($errorTitle,$errorMessage) = split(/\:/,$type_of_error); # The list of the HTTP environment variables are culled # into the @env_vars list array and get_date is used to # assign the current date to $date @env_vars = keys(%ENV); if ($cf{'log_errors'} eq "yes") { # First, the new log entry row is created as a pipe # delimited list beginning with the error type, filename, # line number and current date. my($errorEntry) = $type_of_error; $errorEntry =~ s/\n/ /g; $errorEntry =~ s/\s{2,}/ /g; $log_entry = "Host: $ENV{'REMOTE_ADDR'}\|"; $log_entry .= "IP: $ENV{'REMOTE_HOST'}\|"; $log_entry .= "Query: $ENV{'QUERY_STRING'}\|"; $log_entry .= "$errorEntry\|FILE=$file_name\|LINE=$line_number\|"; $log_entry .= "DATE=$date\|"; # Then the error log file is opened securely by using the # lock file routines in get_file_lock discussed later. $error_log_file = "$cwd$cf{'log_files_path'}/$cf{'error_log_filename'}"; if(!(-e "$error_log_file")) { open (ERROR_LOG, ">$error_log_file")|| &file_error("Cannot create error log file: $error_log_file", $!,__FILE__,__LINE__); close (ERROR_LOG); chmod(0777,$error_log_file); } &get_file_lock("$error_log_file.lockfile"); open (ERROR_LOG, ">>$error_log_file")|| &file_error("Cannot append to error log file: $error_log_file", $!,__FILE__,__LINE__); # Now, the script adds to the log entry row, the values # associated with all of the HTTP environment variables # and prints the whole row to the log file. foreach $variable (@env_vars) { $log_entry .= "$ENV{$variable}\|"; } print ERROR_LOG "$log_entry\n"; close (ERROR_LOG); &release_file_lock("$error_log_file.lockfile"); chmod(0777,$error_log_file); } # End of if log_errors eq "yes" # Next, the script checks to see if the admin has # instructed the script to also send an email error # notification. if ($cf{'send_email_if_error'} eq "yes") { $email_body = "$errorTitle\n"; $email_body .= "$errorMessage\n"; $email_body .= "PAGE = $form_data{'page'}\n\n"; $email_body .= "Helpful Server Environment Variables:\n"; $email_body .= "FILE = $file_name\n"; $email_body .= "LINE = $line_number\n"; $email_body .= "DATE = $date\n\n"; foreach $variable (@env_vars){ $email_body .= "$variable = $ENV{$variable}\n"; } my($subjectLine) = "$cf{'store_name'} Quikstore Error"; @store_email = split(/\,/,$cf{'store_email_address'}); &send_mail($store_email[0],$store_email[0],$subjectLine,$email_body,"store"); } } #-------------------------------------------------------------------- # get_date is used to get the current date and time and # format it into a readable form. The subroutine takes no # arguments and is called with the following syntax: sub get_date { if($debug){ print "get_date \n"; } # We start with the localtime command to get the current time from # the value returned by the time command, splitting it into variables. local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; # Next we read in the strings for the Days and Months # from the language cfg file. if ($hour < 10) { $hour = "0$hour"; } if ($min < 10) { $min = "0$min"; } if ($sec < 10) { $sec = "0$sec"; } if($hour > 12) {$hour = ($hour - 12); $am_pm = "PM";} else{$am_pm = "AM";} $month_num = $mon + 1; $week_day = "day_" . $wday; if($mday < 10){$mday = "0" . $mday;} if($month_num < 10) { $month_number = "month_0" . $month_num; } else { $month_number = "month_" . $month_num; } $date = "$days{$week_day}, $months{$month_number} $mday, $year at $hour\:$min $am_pm"; $year_num = substr($year,2); $short_date = "$month_num-$mday-$year_num"; return ($date, $short_date); } #-------------------------------------------------------------------- # display_price is used to format the price string so that # the store can take into account differing methods for # displaying prices. For example, some countries use # "$xxx.yyy". Others may use "xx.yy UNIT". This # subroutine will use the money_symbol_placement and # the money_symbol variables defined in config file to # format the entire price string for display. sub display_price { if($debug){ print "display_price \n"; } my($price) = @_; my($format_price); $price = &format_price($price); # EURO Pricing if($strings{'use_euro_pricing'} eq "yes") { my($multiplier) = $strings{'euro_multiplier'}; my($euro_price) = &format_price($price * $multiplier); my($euro_label) = $strings{'euro_label'}; if ($strings{'money_symbol_placement'} eq "front") { $format_price = "$strings{'money_symbol'} $price / $euro_label $euro_price"; } else { $format_price = "$price $strings{'money_symbol'} / $euro_label $euro_price"; } } # End if($cf{'use_euro_pricing'} else { if ($strings{'money_symbol_placement'} eq "front") { $format_price = "$strings{'money_symbol'} $price"; } if ($strings{'money_symbol_placement'} ne "front") { $format_price = "$price $strings{'money_symbol'}"; } } # End if($cf{'use_euro_pricing'} = NO or is blank if (($strings{'money_decimal_seperator'} ne "") && ($strings{'money_decimal_seperator'} ne ".")) { $format_price =~ s/\./$strings{'money_decimal_seperator'}/; } return $format_price; } #-------------------------------------------------------------------- # sub add cart ID will insert the current cart_id to # help maintain state while moving throughout the site. # # In the case of the image url for the links from the # thumbnail images, i will also add the number of hits # seen and the category name so that the user will return # back to the proper catalog page. sub add_cart_id { if($debug){ print "add_cart_id \n"; } local ($name, $type) = @_; local ($format_name); $format_name = "$name"; if ($type eq "name") {$format_name =~ s/cart_id=/cart_id=$cart_id/g;} else {$format_name =~ s/cart_id=/cart_id=$cart_id&hits_seen=$hits&category=$format_category/g; } return $format_name; } #-------------------------------------------------------------------- # get_file_lock is a subroutine used to create a lockfile. # Lockfiles are used to make sure that no more than one # instance of the script can modify a file at one time. A # lock file is vital to the integrity of the data. sub get_file_lock { if($debug){ print "get_file_lock \n"; } local ($lock_file) = @_; local ($endtime); $endtime = 20; $endtime = time + $endtime; # We set endtime to wait 20 seconds. If the lockfile has # not been removed by then, there must be some other # problem with the file system. Perhaps an instance of # the script crashed and never could delete the lock file. while (-e $lock_file && time < $endtime) {sleep(10);} open(LOCK_FILE, ">$lock_file")|| &file_error("Cannot create temporary lock file: $lock_file", $!,__FILE__,__LINE__); # Note: If flock is available on your system, feel free to # use it. flock is an even safer method of locking your # file because it locks it at the system level. The above # routine is "pretty good" and it will server for most # systems. But if you are lucky enough to have a server # with flock routines built in, go ahead and uncomment # the next line and comment the one above. # flock(LOCK_FILE, 2); # 2 exclusively locks the file } #-------------------------------------------------------------------- # release_file_lock is the partner of get_file_lock. When # an instance of this script is done using the file it # needs to manipulate, it calls release_file_lock to # delete the lock file that it put in place so that other # instances of the script can get to the shared file. sub release_file_lock { if($debug){ print "release_file_lock \n"; } local ($lock_file) = @_; # flock(LOCK_FILE, 8); # 8 unlocks the file # As we mentioned in the discussion of get_file_lock, # flock is a superior file locking system. If your system # has it, go ahead and use it instead of the hand rolled # version here. Uncomment the above line and comment the # two that follow. close(LOCK_FILE); unlink($lock_file); } #-------------------------------------------------------------------- # format_price is used to format prices to two decimal places. sub format_price { if($debug){ print "format_price \n"; } # The incoming price is set to a local variables and a few # working local variables are defined. local ($unformatted_price) = @_; local ($formatted_price); # Basically, the routine uses the rounding rules of sprintf. # The unformatted_price is rounded to two decimal places and # returned to the calling routine. if (defined $unformatted_price){ #$formatted_price = sprintf ("%.2f", $unformatted_price); $formatted_price = sprintf ("%3.0f", $unformatted_price); } return $formatted_price; } # ------------------------------------------------------------------- sub format_text_field { local($value,$width) = @_; # Very simple. We return the value in $value plus a # string of 25 spaces which has been truncated by the # length of the $value string. return($value . substr((" " x $width), length($value))); } # End of format_text_field #-------------------------------------------------------------------- # Simply Returns the base URL to the script. sub base_url { if($debug){ print "base_url \n"; } local ($ret, $perlwarn); $perlwarn = $^W; $^W = 0; $ret = 'http://' . $ENV{'SERVER_NAME'}; $^W = $perlwarn; $base_url = $ret; return $base_url; } #-------------------------------------------------------------------- # Simply Returns the directory path to the cgi script # and the script name. sub script_url{ if($debug){ print "script_url\n"; } local ($ret, $perlwarn); $perlwarn = $^W; $^W = 0; $ret = 'http://' . $ENV{'SERVER_NAME'} . $ENV{'SCRIPT_NAME'}; $^W = $perlwarn; $script_url = $ret; return $script_url; } #-------------------------------------------------------------------- # Sub Product Weight # Just adds "Weight = lbs." to the weight if the # $database{'product_weight'} field is not null. sub format_product_weight { if($debug){ print "format_product_weight \n"; } local ($productweight, $weight_label) = @_; local ($format_weight); $format_weight = "$productweight"; if ($format_weight <= 0) { $format_weight = ""; } elsif (($format_weight > 0) && ($use_weight_label eq "no")) { $format_weight =~ s/$format_weight/$format_weight/g; } elsif (($format_weight > 0) && ($use_weight_label ne "no")) { $format_weight =~ s/$format_weight/$weight_label $format_weight/g; } return $format_weight; } #-------------------------------------------------------------------- # Sub Product Size # Just adds "Size = xyz" to the size if the # $database{'product_size'} field is not null. sub format_product_size { if($debug){ print "format_product_size \n"; } local ($productsize, $size_label) = @_; local ($format_size); $format_size = "$productsize"; if ($format_size eq "") { $format_size = ""; } elsif ($format_size eq "NA") { $format_size = ""; } elsif (($format_size ne "") && ($use_size_label eq "no")) { $format_size =~ s/$format_size/ $format_size/g; } elsif (($format_size ne "") && ($use_size_label ne "no")) { $format_size =~ s/$format_size/ $size_label $format_size/g; } return $format_size; } # ------------------------------------------------------------------- # Add the link URL if the link is not blank or equal to NA then # add the linking URL to the filename sub format_page_link { if($debug){ print "format_page_link \n"; } local ($page_link, $link_label, $my_category) = @_; local ($format_page_link); local ($format_page_link_label); local ($my_category); $format_page_link = $page_link; $format_page_link_label = $link_label; $blank_field_character = $strings{'blank_field_character'}; $hits = $hits_seen - $sc_db_max_rows_returned; if ($format_page_link eq "NA") { $format_page_link = ""; } elsif ($format_page_link eq $blank_field_character) { $format_page_link = ""; } elsif (! defined $format_page_link) { $format_page_link = ""; } elsif ($format_page_link =~ /http/i) { $format_page_link = qq~ $format_page_link_label~; } else { $format_page_link = qq~ $format_page_link_label~; } return $format_page_link; } #-------------------------------------------------------------------- sub format_na_field { if($debug){ print "format_na_field\n"; } local($na_field) = @_; $blank_field = $na_field; $blank_field =~ s/NA//i; return $blank_field; } #-------------------------------------------------------------------- # Pulls out the product name to be used for linking sub get_product_name { if($debug){ print "get_product_name \n"; } local ($name) = @_; $the_product_name = "$name"; return $the_product_name; } # ------------------------------------------------------------------- sub print_string { if($debug){ print "print_string \n"; } local($string) = @_; local($name); local($value); local($return_string); while (($name, $value) = each(%strings)){ if($name =~ /$string/i){ if($name =~ /email/ig){$value =~ s/
/\n/ig;} $return_string .= "$value\n"; } } return $return_string; } # Get Customer Number Subroutine ------------------------------------ sub get_customer_number{ if($debug){ print "get_customer_number\n"; } my($type) = @_; local($cust_id); local($num); local($number); if($type =~ /order/i){ $cust_num_filepath = "$cwd$cf{'log_files_path'}/$cf{'order_number_file'}"; $number = $cf{'order_number_start'}; if($cf{'reset_order_numbers'} eq "yes"){ $cf{'reset_customer_numbers'} = "yes"; } } else{ $cust_num_filepath = "$cwd$cf{'log_files_path'}/$cf{'customer_number_file'}"; $number = $cf{'customer_number_start'}; } if(!(-e $cust_num_filepath)) { open(NUMBER,">$cust_num_filepath")|| &file_error("Cannot create customer id file: $cust_num_filepath", $!,__FILE__,__LINE__); print NUMBER "$number"; close(NUMBER); chmod(0777,$cust_num_filepath); $num = $number; } elsif((-e "$cust_num_filepath")&& ($cf{'reset_customer_numbers'} eq "yes")) { chmod(0777,$cust_num_filepath); open(NUMBER,">$cust_num_filepath")|| &file_error("Cannot write to customer id file: $cust_num_filepath", $!,__FILE__,__LINE__); print NUMBER "$number"; close(NUMBER); $num = $number; } else { chmod(0777,$cust_num_filepath); open (NUMBER, "<$cust_num_filepath")|| &file_error("Cannot read customer id file: $cust_num_filepath", $!,__FILE__,__LINE__); $num =; close(NUMBER); } if ($num == 99999) { $num = "1"; } else { $num++; } $cust_id = $num; return ($cust_id); } # Increment Number -------------------------------------------------- sub increment_customer_num { if($debug){ print "increment_customer_num \n"; } my($num,$type) = @_; if($type =~ /order/i){ $cust_num_filepath = "$cwd$cf{'log_files_path'}/$cf{'order_number_file'}"; if($num eq "") {$num = $cf{'order_number_start'};} } else{ $cust_num_filepath = "$cwd$cf{'log_files_path'}/$cf{'customer_number_file'}"; if($num eq "") {$num = $cf{'customer_number_start'};} } chmod(0777,$cust_num_filepath); open(NUM,">$cust_num_filepath")|| &file_error("Cannot write to customer id file: $cust_num_filepath", $!,__FILE__,__LINE__); print NUM "$num"; close(NUM); } #-------------------------------------------------------------------- # Error Messages #-------------------------------------------------------------------- # Just a simple place to put all of the error messages and maybe # provide a little extra instruction as to what to do when they happen. # # Basically, it involves two types of errors: # # 1. A file open error # 2. A file require error sub file_error { my($description, $cause, $file, $line) = @_; # The actual Error text... print < InfoDB Script Error The following InfoDB program error has occured:
Error Description: $descriptionCause: $cause
Please review the Troubleshooting Section of the InfoDB
Help for more information about correcting this error.For InfoDB support personnel:
The error occurred in the: $file program at line number: $line