Click to See Complete Forum and Search --> : File reading & writing in loop problem


freefall
03-06-2005, 09:36 PM
I am working on a tiny part of a program I am working on for a web site and the darn thing just won't work.

@displayProducts is transfered in from the URL, generated from a multiple select object. It is then split (I know that it is split right, I have tested that).

What this is supposed to do is take the specified pages out of the products directory and move them to a members-only directory. It also changes the flash header to match the member page. The directory structures in the code are correct.

$product is in the form: familyVehicle/harness/86Y
That is why I parse out everything before the two / for $productName.

The code only generates the first item in @displayProducts. The other files are generated, but they are blank (it writes them all but only reads the first)

Are there any file writing quirks that I am screwing up here?

Thanks!
Ian


foreach $product (@displayProducts) {
my $page = "";

open(INF, "products/$product.shtml");
foreach $line (<INF>) {
$page .= "$line\n";
}
close(INF);

$page =~ s/flash\/head/flash\/head_BH/;

my $productName = $product;
$productName =~ s/^.*\/.*\///g;

open(OUT, ">customers/BrightHorizons/products/$productName.shtml");
print OUT $page;
close(OUT);
}

CyCo
03-07-2005, 11:53 AM
It appears that you really want something like this:
I think... let me know

foreach $product(@displayProducts) {
my $productName = $product;
$productName =~ s/^.*\/.*\///g;
open(INF, "products/$product.shtml");
open(OUT, ">customers/BrightHorizons/products/$productName.shtml");
foreach $line(<INF> ) {
my $page = "";
$page .= "$line\n";
$page =~ s/flash\/head/flash\/head_BH/;
print OUT $page;
}
close(OUT);
close(INF);
}

freefall
03-07-2005, 02:26 PM
That makes more sense but it still only creates output for the first file. You can see the three pages which I generated here: http://www.safertransport.com/customers/BrightHorizons/products/

the 103Z is the first item in the select menu, the first that goes through the file writing sequence.


Oddly enough, I forgot to mention this before, but the others are not blank. They contain the following:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=windows-1252"></HEAD>
<BODY></BODY></HTML>


This isn't coming from my pages because I don't use all-caps for tags.

- Ian

freefall
03-07-2005, 03:42 PM
Here is the entire subroutine copied line-for-line. It might be something else in here


# Featured Product
sub displayProducts {
&login();
if ($loggedIn eq "no") {
return;
}

my @displayProducts = split(/\./, $input{'displayProducts'});

if (scalar(@displayProducts) > 0) {
foreach $product(@displayProducts) {
my $productName = $product;
$productName =~ s/^.*\/.*\///g;

open(INF, "products/$product.shtml");
open(OUT, ">customers/BrightHorizons/products/$productName.shtml");

foreach $line(<INF>) {
$line =~ s/flash\/head/flash\/head_BH/;
print OUT "$line";
}

close(OUT);
close(INF);
}


$announcement = "<center><i>Your Featured Pages have been set.</i></center><br>\n";
$input{'displayProducts'} = "";
&displayProducts();
}
else {
$body .= " Please select which products you would like to list on the Bright Horizons product page.<br><br>\n";
$body .= " Press and hold the Ctrl button while clicking to select multiple products.<br><br>\n";
$body .= " $announcement\n";
$body .= " <center>\n";
$body .= " <form action=\"login.pl\" method=\"get\">\n";
$body .= " <input type=\"hidden\" name=\"action\" value=\"displayProducts\">\n";
$body .= " <select name=\"displayProducts\" multiple=\"true\" size=43>\n";

$body .= " <optgroup label=\"Family Vehicle\">\n";

$body .= " <optgroup label=\" Vests\">\n";
$body .= " <option value=\"familyVehicle/adjustableVest/103z.\">103Z\n";
$body .= " <option value=\"familyVehicle/adjustableVest/203.\">203\n";
$body .= " <option value=\"familyVehicle/nonAdjustableVest/101.\">101\n";
$body .= " <option value=\"familyVehicle/nonAdjustableVest/101PB.\">101PB\n";
$body .= " <option value=\"familyVehicle/nonAdjustableVest/101BR.\">101BR\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Harnesses\">\n";
$body .= " <option value=\"familyVehicle/harnesses/86yHarness.\">86Y\n";
$body .= " <option value=\"familyVehicle/harnesses/kidY.\">KidY\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Mounts\">\n";
$body .= " <option value=\"familyVehicle/mounts/tetherMount.\">100TC\n";
$body .= " <option value=\"familyVehicle/mounts/floorMount.\">100FM\n";
$body .= " <option value=\"familyVehicle/mounts/wheelchairMount.\">100WC\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Boosters\">\n";
$body .= " <option value=\"familyVehicle/boosters/rideRyteBooster.\">Ride Ryte\n";
$body .= " </optgroup>\n";

$body .= " </optgroup>\n";
$body .= " <option value=\"\"></option>\n";
$body .= " <optgroup label=\"School Bus\">\n";

$body .= " <optgroup label=\" Vests\">\n";
$body .= " <option value=\"schoolBus/adjustableVest/103z.\">103Z\n";
$body .= " <option value=\"schoolBus/adjustableVest/203.\">203\n";
$body .= " <option value=\"schoolBus/adjustableVest/225.\">225\n";
$body .= " <option value=\"schoolBus/nonAdjustableVest/zipper.\">101Z\n";
$body .= " <option value=\"schoolBus/nonAdjustableVest/101PB.\">101PB\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Harnesses\">\n";
$body .= " <option value=\"schoolBus/harnesses/86yHarness.\">86Y\n";
$body .= " <option value=\"schoolBus/harnesses/kidY.\">KidY\n";
$body .= " <option value=\"schoolBus/harnesses/1086camHarness.\">1086 Cam\n";
$body .= " <option value=\"schoolBus/harnesses/kidCam.\">Kid Cam\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Mounts\">\n";
$body .= " <option value=\"schoolBus/mounts/seatMount.\">100S\n";
$body .= " <option value=\"schoolBus/mounts/tetherMount.\">100TC\n";
$body .= " <option value=\"schoolBus/mounts/floorMount.\">100FM\n";
$body .= " <option value=\"schoolBus/mounts/wheelchairMount.\">100WC\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Boosters\">\n";
$body .= " <option value=\"schoolBus/boosters/rideRyteBooster.\">Ride Ryte\n";
$body .= " </optgroup>\n";

$body .= " </optgroup>\n";
$body .= " <option value=\"\"></option>\n";
$body .= " <optgroup label=\"Medical Transport\">\n";

$body .= " <optgroup label=\" Vests\">\n";
$body .= " <option value=\"medicalTransport/modifiedVest/m203.\">M203\n";
$body .= " <option value=\"medicalTransport/modifiedVest/101M2.\">101M2\n";
$body .= " </optgroup>\n";

$body .= " <optgroup label=\" Mounts\">\n";
$body .= " <option value=\"medicalTransport/mounts/wheelchairMount.\">100WC\n";
$body .= " </optgroup>\n";

$body .= " </optgroup>\n";

$body .= " </select><br><br>\n";
$body .= " <input type=\"submit\" value=\"Display these Products\"><br><br>\n";
$body .= " </form>\n";
$body .= " <a href=\"login.pl?action=controlPanel\">Return to main control panel</a>\n";
$body .= " </center>\n";
}
}

CyCo
03-08-2005, 01:54 PM
OK, now that I can see what is going on... it looks like you'll need to map the line in red into the foreach loop, since you are using the get method and splitting on the "dot" for your multiple value select list.

if (scalar(@displayProducts) > 0) {
foreach $product(@displayProducts) {
my @displayProducts = split(/\./, $input{'displayProducts'});
my $productName = $product;
$productName =~ s/^.*\/.*\///g;

open(INF, "products/$product.shtml");
open(OUT, ">customers/BrightHorizons/products/$productName.shtml");

foreach $line(<INF> ) {
$line =~ s/flash\/head/flash\/head_BH/;
print OUT "$line";
}

close(OUT);
close(INF);
}

freefall
03-08-2005, 02:28 PM
It still doesn't work... I just don't know what it is!

I've tried it with a standard for loop, I've tried it w/o the regexps, I just don't understand why it goes through the foreach loop for each $product but doesn't write the files...

Once I get it to write those files, I am also going to write a product page which has links to each of these. Hopefully there won't be a problem there.

Thanks

Nedals
03-09-2005, 01:38 AM
I have a few concerns with your script which may or may not be related to your problem.

You call a login sub followed by the line
if ($loggedIn eq "no") { ## where does $loggedIn come from?

Your sub is called displayProducts. You also have an array by the same name. May not be a problem. I just don't like it.

After the foreach loop, you call this sub again. Is that what you really mean to do? There must be a better way!

Totally off topic....
Have you ever used the here-is construct. It will make your HTML output much easier to construct and read.
print <<HTML_OUT;
..
HTML here like this
..
<form action="login.pl" method="get">
<input type="hidden" name="action" value="displayProducts">
<select name="displayProducts" multiple="true" size=43>
..
HTML_OUT

Update: (after a look at your HTML)
I may be wrong here, but I believe that a multiple select will return an array, not a string. So splitting will have no effect.
my @displayProducts = split(/\./, $input{'displayProducts'});

If you are using the CGI module, which you should..
use CGI;
my $q = new CGI;
my @displayProducts = $q->param('displayProducts');