Gossamer Forum
Home : Products : DBMan : Customization :

Order forms, cookies and record updates

(Page 2 of 2)
> >
Quote Reply
Re: Order forms, cookies and record updates In reply to
Carol:

I believe that I have a potential solution to the problem you have been kind enough to join me in wrestling with for the past week.

First, I have concluded that my original hunch was correct and that we cannot assign a JavaScript array element to a Perl scalar. I have concluded this from the fact that what we have developed so far works EXCEPT for the assignments in question, i.e., the following works:

&switch_to_neworders;
$in{'UserID'} = $db_userid;
$in{'Date'} = &get_date;
$in{'Field1'} = $BookletsArray[$i];
$in{'Field2'} = $BookletsArray[$i+1];
open (ID, "<$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) { flock(ID, 1); }
$in{$db_key} = <ID> + 1;
close ID;
open (DB, ">>$db_file_name");
print DB &join_encode(%in);
close DB;
open (ID, ">$db_id_file_name");
print ID $in{$db_key};
close ID;

except for the assignments

$in{'Field1'} = $BookletsArray[$i];
$in{'Field2'} = $BookletsArray[$i+1];

These are left blank in the database while ID, UserID and Date make it in okay.

============

So, I did some searching and I found an HTTP Cookie Library written in Perl from a gentleman by the name of Matt Wright (Matt's Script Archive, http://www.worldwidemart.com/scripts/).

Using this script is quite straightforward:

1) Include it as a required library in the .cfg file as

require $db_script_path . "/cookie.lib";

Matt has several routines for manipulating cookies in his script. The only one we are concerned with is the one which reads cookies:

sub GetCookies {
...
}

2) Recall that the cookies store the user's requests obtained via forms on the client side. To retrieve the information contained in the cookie "Booklets" I call the routine in my userProfile_html.pl script as:

if (&GetCookies('Booklets')) {
...
}

The return value of &GetCookies is 1 if the cookie exists, 0 otherwise. Straightforward enough. I tested the routine. From my form pages the Booklets cookie was created and saved with the information

S1|1

In this case, "S1" is the name of the item and the quantity is "1", with "|" as the delimiter.

Doing a simple Perl "print"

if (&GetCookies('Booklets')) {
print "The Booklets cookie = $Cookies{'Booklets'}"
}

the printed return is

The Booklets cookie = S1%7C1

which is recognized as the URLencoded equivalent of S1|1.

============

Now we have a routine to read the cookie values in native Perl, none of this JavaScript <=> Perl stuff. The question now becomes one of "now that we can read the HTTP cookie in Perl, what is the best way to get it into the database?"

My thoughts at this point are to convert the hash to an array much like what I was doing in JavaScript so that we may still loop through the array for a multiple item order. Your thoughts? There must be a standard library routine out there to take a delimited hash like this and stuff it into an array, I would think. In JavaScript it is very easy:

var Booklets = new Cookie("Booklets")
var BookletsData = Booklets.get()
if (BookletsData != "") {
var BookletsArray = BookletsData.split("|")

Suggestions? Perls of wisdom? ;-)

This may be a good case for your future reference. I am sure I am not the only one interested in getting information from the user via forms, storing the information in a cookie, and having dbman take this cookie info to stuff into a database (I hope so anyway, you have helped a lot! and I tip my hat to you).

Jim

P.S. By the way, I thought the same thing about the while loop, but I figured it was just another one of those wierd Perl things since this is the way it is outlined to be used in the "Perl Programmer's Reference Guide". No other language I know of, including C, C++, Pascal, Modula 2, Ada, Fortran, Basic and JavaScript that I have worked with use the while loop quite like this.
Quote Reply
Re: Order forms, cookies and record updates In reply to
I'm still over my head in this discussion, but I'll hang on with you as long as I can.

When you finish pulling in the data from the cookie, what do you have? Can you give me the full array or hash, complete with example data? And where do you want it to go?



------------------
JPD





Quote Reply
Re: Order forms, cookies and record updates In reply to
Carol:

What I have when the cookie is read is like what I showed:

Doing a simple Perl "print"

if (&GetCookies('Booklets')) {
print "The Booklets cookie = $Cookies{'Booklets'}"
}

the printed return is

The Booklets cookie = S1%7C1

which is recognized as the URLencoded equivalent of S1|1

S1 and 1 is the name and quantity, respectively, of a line item order to be entered into the database as a record (along with the usual $db_userid, and date.

If this were a 2 item order like

S1|1|S5|3

then $Cookies{'Booklets'} would yield

S1%7C1%7CS5%7C3

which we would want in an array like @Booklets which we could loop through twice to generate two records for dbman.

Jim

Quote Reply
Re: Order forms, cookies and record updates In reply to
Here's what I was able to come up with:

Code:
# Decode the cookie
$Cookies{'Booklets'} =~ tr/+/ /;
$Cookies{'Booklets'} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

# Break it up into an array
@BookletsArray = split (/\Q|\E/o,$Cookies{'Booklets'});

Now we're back to having @BookletsArray.

The syntax
Code:
$in{'Field1'} = $BookletsArray[$i];
$in{'Field2'} = $BookletsArray[$i+1];

works just fine.

What exactly is your code for writing to the database file? (I know there's lots of code in this thread, but I'm confused. Smile )


------------------
JPD





Quote Reply
Re: Order forms, cookies and record updates In reply to
Carol:

Yea, I know it's confusing, especially for you switching all the time between requests for your assist.

Anyway, this is the code we had developed up this point, essentially we put the sub add_record in a loop since the cookie can contain any number of orders. We determine the length of the array, divide that by the number of fields per order and that is the resulting number of orders => records in dbman. So if one order contains a name and quantity then the cookie might have the value of S1|2. But if this were a two item order then the cookie might be S4|2|S7|4 (name1=S4, quantity1=2, name2=S7, quantity2=4) with the array looking like

cookieArray[0]=S4
cookieArray[1]=2
cookieArray[2]=S7
cookieArray[3]=4
...

and so on, hence the loop.

========================

Missing item here that I see is determining the length of the array.

# Decode the cookie
$Cookies{'Booklets'} =~ tr/+/ /;
$Cookies{'Booklets'} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# Break it up into an array
@BookletsArray = split (/\Q|\E/o,$Cookies{'Booklets'});

&switch_to_neworders;
if (&GetCookies('Booklets')) {
$i=0;
while ($i < $length) {
$in{'UserID'} = $db_userid;
$in{'Date'} = &get_date;
$in{'Field1'} = $BookletsArray[$i];
$in{'Field2'} = $BookletsArray[$i+1];
open (ID, "<$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) { flock(ID, 1); }
$in{$db_key} = <ID> + 1;
close ID;
open (DB, ">>$db_file_name");
print DB &join_encode(%in);
close DB;
open (ID, ">$db_id_file_name");
print ID $in{$db_key};
close ID;
}
continue {
$i+=2;
}
}
Quote Reply
Re: Order forms, cookies and record updates In reply to
You can find the length of the array by using

Code:
$length = scalar(@BookletsArray) - 1;

Or you can do the same thing without it. I'll show you in the next incarnation of the code.

I notice that you have your "&GetCookies" after we have manipulated the cookies. I think it needs to be turned around.

Code:
&switch_to_neworders;
if (&GetCookies('Booklets')) {

# Decode the cookie
$Cookies{'Booklets'} =~ tr/+/ /;
$Cookies{'Booklets'} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

# Break it up into an array
@BookletsArray = split (/\Q|\E/o,$Cookies{'Booklets'});

$i=0;
while ($BookletsArray[$i]) {
$in{'UserID'} = $db_userid;
$in{'Date'} = &get_date;
$in{'Field1'} = $BookletsArray[$i];
$in{'Field2'} = $BookletsArray[$i+1];
open (ID, "<$db_id_file_name") or &cgierr("error in get_defaults. unable to open id file: $db_id_file_name.\nReason: $!");
if ($db_use_flock) { flock(ID, 1); }
$in{$db_key} = <ID> + 1;
close ID;
open (DB, ">>$db_file_name");
print DB &join_encode(%in);
close DB;
open (ID, ">$db_id_file_name");
print ID $in{$db_key};
close ID;
$i+=2;
}
}

This may not be the way the Perl books say to do it, but it makes more sense to me. Smile


------------------
JPD





Quote Reply
Re: Order forms, cookies and record updates In reply to
Carol:

Your way makes more sense to me, too, so let's go with it. I have done some testing and for the most part, we have success! One small aberation, however, that I think should be easily taken care of.

The example below is what is pulled from the newOrders.db It is the information for a 4 item order entry, a 2 item order, then a single item order. As you can see, record 1 is a dash followed by the four order entry of S1->S4. The next order is for two items S15 and S16, then the single order of S18. Each order is preceded by the dash entry.

1|admin|29-Mar-2000|-&#0124; &#0124;&#0124; &#0124;|
2|admin|29-Mar-2000|S1|1&#0124; &#0124;&#0124; &#0124;
3|admin|29-Mar-2000|S2|1&#0124; &#0124;&#0124; &#0124;
4|admin|29-Mar-2000|S3|1&#0124; &#0124;&#0124; &#0124;
5|admin|29-Mar-2000|S4|1&#0124; &#0124;&#0124; &#0124;
6|admin|29-Mar-2000|-&#0124; &#0124;&#0124; &#0124;|
7|admin|29-Mar-2000|S15|2&#0124; &#0124;&#0124; &#0124;
8|admin|29-Mar-2000|S16|2&#0124; &#0124;&#0124; &#0124;
9|admin|29-Mar-2000|-&#0124; &#0124;&#0124; &#0124;|
10|admin|29-Mar-2000|S18|3&#0124; &#0124;&#0124; &#0124;

I repeated this experiment and found it to be consistent...all subsequent additions to the database via additional orders always start out with this dashed record entry.

Now, I will tell you upfront that I know just enough about regular expressions to know that I can get myself into real trouble over them so I will defer to your expertise and not even attempt at the resolution. But, like I said, I would suspect that the resolution is simple enough.

Jim
Quote Reply
Re: Order forms, cookies and record updates In reply to
It would seem, then, that your @BookletsArray starts with a - and then another character and then the data you want.

If this is consistent, try changing

Code:
$i = 0;

to

Code:
$i = 2;



------------------
JPD





> >