eXtropia: the open web technology company
Technology | Support | Tutorials | Development | About Us | Users | Contact Us
Free support
 ::   Support forums
 ::   Frequently asked questions
 ::   Functional Specifications
 ::   eXtropia Tutorials
 ::   Books by eXtropia
 ::   Other books
 ::   Offsite resources
eXtropia FAQs

eXtropia Installation and Customization FAQ
I'm having trouble with Macromedia Dreamweaver and eXtropia scripts. What's up?
When mailing, how would I verify the user's e-mail address by having e-mail messages returned to me if a user enters a bogus, but otherwise correctly formatted address?
In WebCal, how do I add buttons for Next Month and previous Month?
How do I send e-mail receipts to clients in the WebStore?
How can I post multiple tax rates for stores in different parts of the country in WebStore?
How do I use images for my HTML form submit buttons?
I have a form and when the user hits the "enter" key, the form submits. However, when this happens, the submit button does not have a value. Since I use the value of the submit button to determine what action the script should perform, my script breaks. How can allow the user to hit the enter key without messing up my script?
I would like to use the /etc/passwd file with your authentication libraries so that people could use their system username and password to login to my CGI applications. How do I do so?
In WebStore, how can I give each individual item its own shipping price?
 


Q: I'm having trouble with Macromedia Dreamweaver and eXtropia scripts. What's up?

A: Frank Rickett sent in this useful bit of info....

The Problem: Webauthenticate. HTML files fail to hold the &session information and appear not to have been filtered by the www_secure.cgi program.

The Cause/Solution. If you are using Macromedia Dreamweaver and you insert the links via the property inspector dialogue box, it encodes the ampersand character as html code for ampersand, so what gets placed into the page at a text level looks like this: &session.

This doesn't look like &session to the cgi script and so is not substituted for the session code when the page is requested. The solution - edit the &session part of the link via the html/text interface to ensure its encoded the way you want.


Q: When mailing, how would I verify the user's e-mail address by having e-mail messages returned to me if a user enters a bogus, but otherwise correctly formatted address?

A: In mail-lib.pl, at line 92, set

$flags = "-t -f";

The -f option, which is not available on all platforms, inserts a "Return To" into the e-mail message, having the effect of returning (bounce back) undeliverable mail to the the specified address.

Thanks to Ignacio for suggesting this modification!


Q: In WebCal, how do I add buttons for Next Month and previous Month?

A: MarkMetl@MarkMetl.Com took some time to work through this problem and sent in his solution...

The gist of the solution is that you are going to need to create a hyperlink which contained all of the informaiton that the script will need such as:

http://www.you.com/cgi-bin/webcal.cgi?session=blahblah? calendar=blahblah&month=10&year=1998$submit=change_month_year

Your script will know alot of info itself. For example, it should know the session, calendar, current month, current year. You would need to make your link use $month-1 and $month+1 execpt the beginning and ending of the year which then modifies the $year value. Here is how Mark worked it out....

"This appears to do the trick! (Inserted under the page header. ~line 168.)"


$variable_list = "";
$variable_list .= "calendar=$form_data{'calendar'}";
$variable_list .= "&change_month_year=on";
$variable_list .= "&session_file=$session_file";
$next_month = $currentmonth + 1;
$next_year = $currentyear;
$prev_month = $currentmonth - 1;
$prev_year = $currentyear;
if ($next_month > 12)
    {
    $next_month = 1;
    $next_year++;
    }
if ($prev_month < 1)
    {
    $prev_month = 12;
    $prev_year--;
    }
$next_link = $variable_list .
             "&month=$next_month&year=$next_year";
$prev_link = $variable_list .
             "&month=$prev_month&year=$prev_year";
$month_link = "calendar=$form_data{'calendar'}" .
             "&session_file=$session_file";
$month_link .= "&month=$currentmonth&year=" .
             "$currentyear&view_month=on";
print qq!
<CENTER>
<TABLE>
<TR>
<TD ALIGN="left" VALIGN="bottom"
       WIDTH="280">
<FONT SIZE="1">
<A HREF="$this_script_url?$prev_link">Last
      Month</A>
</FONT>
</TD>
<TD ALIGN="right" VALIGN="bottom"
       WIDTH="280">
<FONT SIZE="1">
<A HREF="$this_script_url?$next_link">Next
           Month</A>
</FONT>
</TD>
</TR>
</TABLE>
<TABLE BORDER="2" CELLPADDING="2"
          CELLSPACING="1">
<TR>
<TD COLSPAN="7" ALIGN="center"
       BGCOLOR=$apptcol>
<B>
<FONT COLOR="$hitxt">$current_month_name
                        - $current_year
</FONT>
</B>
</TD>
</TR>
<TR>!;


Q: How do I send e-mail receipts to clients in the WebStore?

A: Angelina Hedgepeth and Ignaciao Bustamonte (iggiebee@rhpworld.org) submitted the following explanation:

First we add a new global variable to the setup file in order to be able to toggle this condition (send e-mail to customer).

Insert it with the other mail related variables. If you don't know where they are, look for the: $sc_send_order_to_email = "yes";, and insert the follwoing line right beneath it:

   $sc_send_order_to_customer = "yes";

Then, on "web_store_order_lib.pl" we add the following changes on the Process_order_form function:

(BTW, on this, Ignacio made changes that you may have to modify on the section that tests for sensitive Credit Card information so that it will not be e-mailed, and substitute for your own variables. They look like this:

       $sc_order_form_array{$form_field} eq "Name
              Appearing on Card" , etc.

(These variables are established in the setup file "Order Form Definition Variables" section).

Also check that the new call to the send_mail function (to customer) contains the propper form_data value.

Finally, please limit yourself to the changes that have to do with e-mailing to customer (copy and paste as necessary), there is other stuff in this function that I have modified and it may not work with the normal web_store.cgi.

What follows is the Ignaciao's text for the process_order_form subroutine.

        # IBM 06-09-97 added new local variable
        # $text_of_cart_to_customer
        # This variable will hold same content
        # as $text_of_cart
        # without Credit card Information.

sub process_order_form
  {
  local($subtotal, $total_quantity,
        $total_measured_quantity,
        $text_of_cart,
        $required_fields_filled_in);
  local($text_of_cart_to_customer);

        # We check the Required Fields
        # If they are all correct we
        # generate a header with a META
        # tag to reaload Web Store and force
        # a new Cart ID

  $required_fields_filled_in = "yes";

  foreach $required_field
          (@sc_order_form_required_fields)
      {
      if ($form_data{$required_field} eq "")
        {
        $required_fields_filled_in = "no";
        }
      }

  if ($required_fields_filled_in eq "no")
    {

        # We output the header of
        # the processing of the order
        # without the META tag to allow
        # the user to return and make the
        # appropriate changes

    print qq!
    <HTML>
    <HEAD>
    <TITLE>Processing The Order
                 Form</TITLE>
    </HEAD>
    <BODY BGCOLOR = "#FFFFE8"
             TEXT = "000000">
    <CENTER>!;
    }
  else
    {

        # We output the header of
        # the processing of the order
        # with the META tag

    print qq!
    <HTML>
    <HEAD>
    <TITLE>Processing The Order
                 Form</TITLE>
    <META HTTP-EQUIV="refresh"
             CONTENT="10;URL=
    https://www.domain.com/cgi/web_store.cgi">
    </HEAD>
    <BODY BGCOLOR = "#FFFFE8"
             TEXT = "000000">
    <CENTER>!;
    }

        # if $required_fields_filled_in
        # is set to "no"
        # output the necessary warnings
        # for each missing required field

  if ($required_fields_filled_in eq "no")
    {
    print qq!
    <TABLE BORDER=1>
    <TR>
    <TD>
    <FONT COLOR=red>
    <B>You forgot to fill in: </B>
    </FONT>
    </TD>
    </TR>\n!;

    foreach $required_field
          (@sc_order_form_required_fields)
      {
      if ($form_data{$required_field} eq "")
        {
        print qq!
        <TR>
        <TD ALIGN=left>
        <FONT SIZE=-1 COLOR=blue>
        <B>!;
        print $sc_order_form_array{$required_field};
        print qq!</B>
        </FONT>
        <BR>
        </TD>
        </TR>\n!;
        }
      }
    print "</TABLE>\n";
    }

  print "<HR>\n";

  if ($required_fields_filled_in eq "no")
    {

        # The user is notified that
        # the order
        # was not a success

    print qq!
    <FONT COLOR=red>
    <H2>Sorry...Your Order Has Not
              Been Sent...</H2>
    </FONT>
    </CENTER>
    Please use the <FONT COLOR=blue>
    <b>
    <i>Back Button</i>
    </b>
    </FONT>
    to return to the previous page and enter the
    information for the
    <FONT COLOR=blue>
    <b>
    <i>
    Items listed above.</i>
    </b>
    </FONT>
    <P>\n!;
    }
  else
    {

        # The user is notified that the order
        # was a success

    print qq!
    <FONT COLOR=red>
    <H2>
    Thank You...Your Order Has Been Sent...
    </H2>
    </FONT>
    <FONT COLOR=blue>
    <b>
    <i>
    We appreciate your business.
    </i>
    </b>
    </FONT>
    </CENTER>
    <P>\n!;
    }
        # We display the cart table.
        # This also has the effect of
        # populating the text_of_cart
        # variable with the ASCII text version
        # of the cart for emailing/logging
        # the order that is being processed.

  ($subtotal,
   $total_quantity,
   $total_measured_quantity,
   $text_of_cart) =
   &display_cart_table("process order");

        # Now that the sub-total has been
        # obtained from the cart, we
        # can calculate shipping, sales tax,
        # discount, and grand total. This
        # new information is appended to
        # the $text_of_cart variable.

   $text_of_cart =
   &display_calculations($subtotal, "at",
                         $text_of_cart);


       # Now that we have the text of the cart
       # all together. We check the required
       # form fields from the previous form
       # to see if they were filled in by the
       # user


    print "<HR>\n";

       # Since the required fields were
       # filled in correctly, we process
       # the rest of the order

    if ($required_fields_filled_in eq "yes")
      {
      # The $text_of_cart is appended with all
      # the values for the form that the user
      # has entered into the system.

      # IBM 06-09-97 next line
      # Fill $text_of_cart_to_customer
      # with contents of $text_of_cart

      $text_of_cart_to_customer = $text_of_cart;

      # IBM 06-09-97 Modify code
      # To skip Credit card Information
      #  when updating $text_of_cart_to_customer
      #
      # old code:
      #   foreach $form_field
      #   (sort(keys(%sc_order_form_array))) {
      #    $text_of_cart .=
      #      &format_text_field
      #      ($sc_order_form_array{$form_field})
      #      . "= $form_data{$form_field}\n";
      #  }

 foreach $form_field
         (sort(keys(%sc_order_form_array)))
    {
    $text_of_cart .=
      &format_text_field
      ($sc_order_form_array{$form_field})
      . "= $form_data{$form_field}\n";

      # next 7 lines skip credit card info
      # and add string to
      #$text_of_cart_to_customer

     unless ($sc_order_form_array{$form_field} eq
            "Name Appearing on Card" ||
            $sc_order_form_array{$form_field} eq
            "Card Number" ||
            $sc_order_form_array{$form_field} eq
            "Card Expiration" )
         {
         $text_of_cart_to_customer .=
         &format_text_field
         ($sc_order_form_array{$form_field})
         . "= $form_data{$form_field}\n"; }
         }


  $text_of_cart .= "\n";

      # IBM 06-09-97 Add code
      # Add final carriage return

  $text_of_cart_to_customer .= "\n";

      # If PGP (Pretty Good Privacy) is in
      # use, then we translate the text of the
      # cart to a PGP encrypted form using
      # the pgp-lib.pl file that we provided
      # with the web_store.

  if ($sc_use_pgp =~ /yes/i)
    {
    &require_supporting_libraries
       (__FILE__, __LINE__,
        "$sc_pgp_lib_path");
  $text_of_cart = &make_pgp_file
        ($text_of_cart,
        "$sc_pgp_temp_file_path/$$.pgp");
  $text_of_cart = "\n" .
                  $text_of_cart . "\n";
    }

     # If we are sending the order through
     # email, then we use the mail-lib.pl
     # send_mail routine.

  if ($sc_send_order_to_email =~ /yes/i)
      {
      &send_mail($sc_order_email,
                 $sc_order_email,
                 "Web Store Order",
                 $text_of_cart);
      }

# IBM 06-09-97 New code
# Send e-mail to customer
# if required in setup file
# We grab the e-mail address
# of the customer from
# the Order Form Definition Variables
# contained in the setup file

  if ($sc_send_order_to_customer =~ /yes/i)
    {
    &send_mail($form_data{"14-e-mail"},
               $form_data{"14-e-mail"},
               "Web Store Order Customer Copy",
               $text_of_cart_to_customer);
   }

# If we are sending the order to
# a log file. Then, we use the following
# routine to append to the log file
# specified in the setup.
#
# The entries in the log file
# are separated by two lines of
# 40 hyphens ("-" x 40)
#

  if ($sc_send_order_to_log =~ /yes/i)
    {
    open (ORDERLOG, ">>
          $sc_order_log_file");
    print ORDERLOG "-" x 40;
    print ORDERLOG $text_of_cart;
    print ORDERLOG "-" x 40 . "\n";
    close (ORDERLOG);
  }
}

# The footer is printed

print "
\n"; print qq! </BODY> </HTML> !; } # End of process_order_form


Q: How can I post multiple tax rates for stores in different parts of the country in WebStore?

A: Milan C Shah webmaster@virtualscribe.com posted the following explanation:

Tax has been redefined to become dependent on many variables, just like shipping and discount, instead of being a constant.

Originally, tax had been defined in the Web Store as a constant, and the dependant variable was posted just below it:

Within *setup.db.table, for the database driven store, the following have been stated

$sc_sales_tax = ".0775"; # 7.75%
$sc_sales_tax_form_variable = "04-b_state";
@sc_sales_tax_form_values = ("il",
                             "Illinois");

These should be removed, and in place goes the following definition:

   @sc_tax_logic =("al|1-|||4%",
                   "il|1-|||7.75%",
                   "wi|1-|||5.6%");

Like shipping and discount, they can take many forms and be dependent on any variables. Further, we define a new array

@sc_order_form_tax_related_fields =
    ("04-b_state");

just below @sc_order_form_shipping_related_fields... and @sc_order_form_discount_related_fields to assign the dependency to the Billing State.

Finally, the outlet_order_form_with_shipping.html needs to have the states coded within a form selection, so as not to leave the 2 letter abbreviation to chance:

   <SELECT  NAME="04-b_state">
   <OPTION VALUE="" SELECTED>
       Please Select a State
   <OPTION VALUE="al">Alabama
   <OPTION VALUE="il">Illinois
   <OPTION VALUE="wi">Wisconsin
   <OPTION VALUE="other">All
       Other States
   </SELECT>

Those 3 changes should do it. Again, adding dependency and defining tax to be variable in *setup.db.table, and hard coding the states in outlet_order_form_with_shipping.html handle multiple states and their taxes.


Q: How do I use images for my HTML form submit buttons?

A: There is a good introductory discussion of how to implement image buttons in Chapter 25 of Instant Web Scripts with CGI/PERL. The chapter is available online at http://www.extropia.com/books/instant_web_scripts/chap25.html

However, essentially, you will need to change the way the script handles submit buttons. Usually, you will create a form like:

   <FORM METHOD = "POST"
            ACTION = "myScript.cgi">
   Submit your email address:
   <INPUT TYPE =  "TEXT"
             NAME = "email">
   <INPUT TYPE = "SUBMIT"
             NAME = "emailValue">
   </FORM>

In your CGI script you would probably handle that input using code such as:

   if ($in{'emailValue'} ne "")
	{
	print $in{'emailValue'}\n;
	}

However, if you were to use an image for your submit button such as in the following example:


   <INPUT TYPE = "IMAGE"
             NAME = "emailValue"
             SRC = "email_submit.gif"
             BORDER = "0">

You would have to process it a little bit differently. Specifically, the web server would send you an image map click location value in two pieces. The x coordinate of the user's mouse click would be sent as emailValue.x and the y value of the user's mouse click would be sent as emailValue.y. So if you want to see if a user clicked a button, just check to make sure if either emailValue.x or emailValue.y have a value such as:


   if ($in{'emailValue.x'} ne "")
	{
	print $in{'emailValue'}\n;
	}


Q: I have a form and when the user hits the "enter" key, the form submits. However, when this happens, the submit button does not have a value. Since I use the value of the submit button to determine what action the script should perform, my script breaks. How can allow the user to hit the enter key without messing up my script?

A: Add a HIDDEN tag whose value and name are the same as the value and name of the SUBMIT button for the query. For example, if you have the following inout button:

<INPUT TYPE = "SUBMIT"
          NAME = "search_request_button"
          VALUE = "Go Search!">

You should add the follwong HIDDEN input:

<INPUT TYPE = "HIDDEN"
          NAME = "search_request_button"
          VALUE = "Go Search!">


Q: I would like to use the /etc/passwd file with your authentication libraries so that people could use their system username and password to login to my CGI applications. How do I do so?

A: In theory, yes you could certainly use the contents of the etc/passwd file for authentication. The passwords in that file are encrypted the same way we encrypt our passwords in the authentication library.

HOWEVER....

You almost certainly do not want to do this. You must understand that the web server is a very poorly defended gateway, nay, a wide open doorway, to the whole internet. The internet is filled not only with friendly hackers, but also not-so-friendly crackers.

The minute you give your web server access to etc/passwd is the minute you invite a cracker to come in and grab that file, pass it through a password file cracking program, and break into your computer system.


Q: In WebStore, how can I give each individual item its own shipping price?

A: This answer was submitted by Angelina Hedgepeth and Ignaciao Bustamonte (iggiebee@rhpworld.org)

Step One: In WEB_STORE_ORDER_PL, you should locate the subroutine: calculate_final_values which should read:

  if ($sc_calculate_shipping_at_display_form
      == $calc_loop)
      {
      $shipping =
      &calculate_shipping($temp_total,
                $total_quantity,
                $total_measured_quantity);
      } # End of shipping calculations

and replace it with the following code:

  if ($sc_calculate_shipping_at_display_form ==
      $calc_loop)
      {
      $shipping =
      $total_measured_quantity;
      } # End of shipping calculations

Next, you'll move down just a few lines to find the following bit of code:

  if ($sc_calculate_shipping_at_process_form
    == $calc_loop)
      {
      $shipping =
      &calculate_shipping($temp_total,
                  $total_quantity,
                  $total_measured_quantity);
      } # End of shipping calculations

You should replace that with the following:

  if ($sc_calculate_shipping_at_process_form
      == $calc_loop)
      {
      $shipping =
      $total_measured_quantity;
      } # End of shipping calculations

Now save that and open WEB_STORE_HTML_LIB_PL. In this file, find the code which reads:

    $db{"product_id"} = 0;
    $db{"product"} = 1;
    $db{"price"} = 2;
    $db{"name"} = 3;
    $db{"image_url"} = 4;
    $db{"description"}= 5;
    $db{"options"} = 6;

You should replace that code with the following:

    $db{"product_id"} = 0;
    $db{"product"} = 1;
    $db{"price"} = 2;
    $db{"name"} = 3;
    $db{"image_url"} = 4;
    $db{"description"}= 5;
    $db{"shipping"} = 6;
    $db{"options"} = 7;

Next, replace the follwing code:

    @sc_db_index_for_defining_item_id =
    ($db{"product_id"},
    $db{"product"},
    $db{"price"},
    $db{"name"},
    $db{"image_url"});

with the following code:

    @sc_db_index_for_defining_item_id =
    ($db{"product_id"},
    $db{"product"},
    $db{"price"},
    $db{"name"},
    $db{"image_url"},
    $db{"shipping"});

Then, you should replace

    $cart{"quantity"} = 0;
    $cart{"product_id"} = 1;
    $cart{"product"} = 2;
    $cart{"price"} = 3;
    $cart{"name"} = 4;
    $cart{"image_url"} = 5;
    $cart{"options"} = 6;
    $cart{"price_after_options"} = 7;
    $cart{"unique_cart_line_id"} = 8;

with


    $cart{"quantity"} = 0;
    $cart{"product_id"} = 1;
    $cart{"product"} = 2;
    $cart{"price"} = 3;
    $cart{"name"} = 4;
    $cart{"image_url"} = 5;
    $cart{"shipping"} = 6;
    $cart{"options"} = 7;
    $cart{"price_after_options"} = 8;
    $cart{"unique_cart_line_id"} = 9

Next, replace this code:

    $sc_cart_index_of_measured_value =
        $cart{"price"};

    @sc_cart_display_fields =
        ("Description",
        "Image",
        "Options",
        "Price After Options");

    @sc_cart_index_for_display =
        ($cart{"name"},
        $cart{"image_url"},
        $cart{"options"},
        $cart{"price_after_options"});

With this code:

    $sc_cart_index_of_measured_value =
        $cart{"shipping"};

    @sc_cart_display_fields =
        ("Description",
        "Image",
        "Shipping per Item
        "Options",
        "Price After Options");

    @sc_cart_index_for_display =
        ($cart{"name"},
        $cart{"image_url"},
        $cart{"shipping"},
        $cart{"options"},
        $cart{"price_after_options"});

Finally, replace the shipping logic code you have (for example)

    @sc_shipping_logic =
    ("|11-||7%",
    "|7-10||10%",
    "|1-2||4");

with

    @sc_shipping_logic = ();