can't get code dealing with arrays to work
Posted: Fri Jun 04, 2010 7:09 pm
I'm using oscommerce for my website's shopping cart, which uses php. And there is a shipping function which has various tables defined. Actually it only had one table until I added things to it. But it has a table delimited by commas and colons, for determining shipping cost by weight. For instance, 5:3.62,16:6.1,29:8.89 would charge a customer $3.62 if the weight was less than or equal to 5, but failing that, if it was still no more than 16, it would charge $6.10, and if not, then as long as it was less than 29 units of whatever, it would charge $8.89. I added an insurance table to it, so that there was a shipping cost measured in units of weight, but an insurance cost which has the same format but uses the order subtotal as its input variable.
Now it also has many different zones, and each zone has an array of different countries. The point being that every country in the list for one particular zone gets treated the same way. So being in the United States, for instance, it costs me the same to ship to France as to England. However, shipping to Canada is cheaper. So Canada would get its own zone, the United States certainly gets its own zone, but England and France are separate countries in the same zone. As it so happens, I have 5 zones defined. US is one. Canada another. Mexico another. Japan, most of Europe, Greenland, and Australia is another. And the fifth contains some others, like Anguilla, New Zealand and Israel. Not that I expect to ship to these countries very often. But my point is there are 5 separate zones, each of which contains a TABLE of countries. Now in researching shipping and insurance costs, I noticed that there is a free insurance called an "automatic indemnity" which comes with shipping internationally, but it is country-dependent. And it turns out that in all other aspects, all the countries in my 4th zone (which contains Japan, Europe, Greenland and Australia) have identical shipping costs BUT different indemnity limits. And my 5th zone, well EVERY ONE of them is different in the indemnity limit. So if I had an insurance table like 100:1,200:2,300:3,400:4,500:4,600:6 that would mean the customer gets charged a dollar for each hundred dollars he's insuring. BUT suppose insurance comes free if it is up to 415 dollars for one country, but I only get 70 dollars of free insurance for a different country, and both these countries are in the zone of consideration which use the same table aside from the automatic indemnity. In other words, in all other aspects, it costs the same to ship or insure to country A and country B for a given weight and price, BUT if the subtotal is between 70.01 and 415 then I can get insurance for free to country A but not to B. So I want it to check, WITHIN the table, which country it is going to, and if country A, then IDEALLY turn the table into 70:0,100:1,200:2,300:3,400:4,500:5,600:6, and if country B, then turn the table into 415:0,500:5,600:6. It would of course be, for all intents and purposes, equivalent if it changed the table, if country B, to 415:0,415:0,415:0,415:0,500:5,600:6. I don't really care which one it does, and so I tried implementing my code each way. And the same problem appears for both. But what I want to do is if the coverage anywhere in the array is less than the country-specific automatic indemnity, in this case 415, then the first number gets overwritten with the country-specific automatic indemnity and the second number, the cost for that level of coverage, gets overwritten with 0. I have made some code that SHOULD do this, or rather something close to it - its only failing that it SHOULD theoretically have is that it won't insert into the table to make it longer - I don't know what in theory would allow me to allocate an extra element into an array - so for it to work with country A, it needed to start with maybe 0:0,100:1,200:2,300:3,400:4,500:4,600:6, and then the 0:0 would get overwritten with 70:0. But it unfortunately doesn't work at ALL. The whole table rate stops working. Instead of throwing the indemnity in there making things at worst the same and at best cheaper, with free insurance possibly being available, that particular component doesn't work at all. None of my variables are typed wrong, I have done the code for this several different ways, and everything that SHOULD work just doesn't. Now look at this part below:
Now, this is where it determines the zone within the set of several possible zones. I didn't write this part. It searches through all the countries in a list defined for each zone to see if it matches the country of the customer. If so, it uses that zone. In other words, if shipping to France, it will eventually settle on zone 3 because the country table for zone 3 is "JP,GB,GL,DK,ES,PT,CH,LI,NL,MC,PL,GR,AU,SE,IS,IE,BE,NO,DE,FI,FR,IT" and it contains the letters "FR". Of course, first it turns the comma-delimited monstrosity into an array. But it doesn't keep track of the position of the country in that table of countries, it just says "the customer's country is somewhere in this list, so we use this zone". It doesn't know, just from this, that "FR" is the 21st element in this list and in the array will have index 20. But if I want a country-specific automatic indemnity then I have to recover which country in the zone it is, you see. And I have another table defined side by side with the country list which is MODULE_SHIPPING_ZONES3_FREE_INDEMNITY_ and this is a list of indemnity coverages that respectively should go with each country in the list. So if some country table was "US,CA,MX,IT" and the indemnity table was "4400,2200,68,650" then it should give an indemnity coverage of 4400 dollars if the customer is in the US, 2200 if Canada, 68 if in Mexico, 650 if Italy. So I try to accomplish this by having it later search through the country table to see where in the country list the customer's country is, and it takes the index it finds, and uses the same place in the table produced from $zones_indemnity_table which is a table produced from the comma-delimited MODULE_SHIPPING_ZONES3_FREE_INDEMNITY_ and uses that value in that table to fit into the first term of $zones_alternate_insurance_table as well as $zones_insurance_table if the shipping weight is above a certain threshold. The trouble is, when it does this, it just doesn't work for some reason. This is the specific code I wrote withing the whole function to accomplish this:
What this should do is if the country's indemnity is say, 415 dollars, and the insurance array looks like this:
100:1,200:2,300:3,400:4,500:5,600:6, it should change it to be like this: 415:0,500:5,600:6 in two separate tables, the alternate insurance table and the insurance table, but only do the insurance table if it is above a certain threshold. I redid it so that it would instead turn it into 415:0,415:0,415:0,415:0,500:5,600:6 with this code:
Maybe you know something about how these arrays work and I'm not following the right format with something. Please help. Thanks.
Now it also has many different zones, and each zone has an array of different countries. The point being that every country in the list for one particular zone gets treated the same way. So being in the United States, for instance, it costs me the same to ship to France as to England. However, shipping to Canada is cheaper. So Canada would get its own zone, the United States certainly gets its own zone, but England and France are separate countries in the same zone. As it so happens, I have 5 zones defined. US is one. Canada another. Mexico another. Japan, most of Europe, Greenland, and Australia is another. And the fifth contains some others, like Anguilla, New Zealand and Israel. Not that I expect to ship to these countries very often. But my point is there are 5 separate zones, each of which contains a TABLE of countries. Now in researching shipping and insurance costs, I noticed that there is a free insurance called an "automatic indemnity" which comes with shipping internationally, but it is country-dependent. And it turns out that in all other aspects, all the countries in my 4th zone (which contains Japan, Europe, Greenland and Australia) have identical shipping costs BUT different indemnity limits. And my 5th zone, well EVERY ONE of them is different in the indemnity limit. So if I had an insurance table like 100:1,200:2,300:3,400:4,500:4,600:6 that would mean the customer gets charged a dollar for each hundred dollars he's insuring. BUT suppose insurance comes free if it is up to 415 dollars for one country, but I only get 70 dollars of free insurance for a different country, and both these countries are in the zone of consideration which use the same table aside from the automatic indemnity. In other words, in all other aspects, it costs the same to ship or insure to country A and country B for a given weight and price, BUT if the subtotal is between 70.01 and 415 then I can get insurance for free to country A but not to B. So I want it to check, WITHIN the table, which country it is going to, and if country A, then IDEALLY turn the table into 70:0,100:1,200:2,300:3,400:4,500:5,600:6, and if country B, then turn the table into 415:0,500:5,600:6. It would of course be, for all intents and purposes, equivalent if it changed the table, if country B, to 415:0,415:0,415:0,415:0,500:5,600:6. I don't really care which one it does, and so I tried implementing my code each way. And the same problem appears for both. But what I want to do is if the coverage anywhere in the array is less than the country-specific automatic indemnity, in this case 415, then the first number gets overwritten with the country-specific automatic indemnity and the second number, the cost for that level of coverage, gets overwritten with 0. I have made some code that SHOULD do this, or rather something close to it - its only failing that it SHOULD theoretically have is that it won't insert into the table to make it longer - I don't know what in theory would allow me to allocate an extra element into an array - so for it to work with country A, it needed to start with maybe 0:0,100:1,200:2,300:3,400:4,500:4,600:6, and then the 0:0 would get overwritten with 70:0. But it unfortunately doesn't work at ALL. The whole table rate stops working. Instead of throwing the indemnity in there making things at worst the same and at best cheaper, with free insurance possibly being available, that particular component doesn't work at all. None of my variables are typed wrong, I have done the code for this several different ways, and everything that SHOULD work just doesn't. Now look at this part below:
Code: Select all
for ($i=1; $i<=$this->num_zones; $i++) {
$countries_table = constant('MODULE_SHIPPING_ZONES3_COUNTRIES_' . $i);
$country_zones = split("[,]", $countries_table);
if (in_array($dest_country, $country_zones)) {
$dest_zone = $i;
break;
}
}Code: Select all
$zones_indemnity_cost = constant('MODULE_SHIPPING_ZONES3_FREE_INDEMNITY_' . $dest_zone);
$zones_indemnity_table = split("[,]", $zones_indemnity_cost);
$altinsursize = sizeof($zones_alternate_insurance_table);
$insursize = sizeof($zones_insurance_table);
$i=0;
while ($dest_country != $country_zones[$i]) { $i++; }
if ($zones_indemnity_table[$i] > 0) {
$j=0;
while (($j < $altinsursize) && ($zones_alternate_insurance_table[$j] <= $zones_indemnity_table[$i])) {
$j+=2;
}
if ($j) {
$j-=2;
$zones_alternate_insurance_table[0] = $zones_indemnity_table[$i];
$altinsursize = $altinsursize - $j;
for ($k=1; $k < $altinsursize; $k++) {
$zones_alternate_insurance_table[$k] = $zones_alternate_insurance_table[$k + $j];
}
}
if ($shipping_weight > $zones_insurance_threshold1) {
$j=0;
while (($j < $insursize) && ($zones_insurance_table[$j] <= $zones_indemnity_table[$i])) {
$j+=2;
}
if ($j) {
$j-=2;
$zones_insurance_table[0] = $zones_indemnity_table[$i];
$insursize = $insursize - $j;
for ($k=1; $k < $insursize; $k++) {
$zones_insurance_table[$k] = $zones_insurance_table[$k + $j];
}
}
}
}What this should do is if the country's indemnity is say, 415 dollars, and the insurance array looks like this:
100:1,200:2,300:3,400:4,500:5,600:6, it should change it to be like this: 415:0,500:5,600:6 in two separate tables, the alternate insurance table and the insurance table, but only do the insurance table if it is above a certain threshold. I redid it so that it would instead turn it into 415:0,415:0,415:0,415:0,500:5,600:6 with this code:
Code: Select all
$zones_indemnity_cost = constant('MODULE_SHIPPING_ZONES3_FREE_INDEMNITY_' . $dest_zone);
$zones_indemnity_table = split("[,]", $zones_indemnity_cost);
$altinsursize = sizeof($zones_alternate_insurance_table);
$insursize = sizeof($zones_insurance_table);
$i=0;
while ($dest_country != $country_zones[$i]) { $i++; }
if ($zones_indemnity_table[$i] > 0) {
for ($j=0; (($j < $altinsursize) && ($zones_alternate_insurance_table[$j] <= $zones_indemnity_table[$i])); $j+=2) {
$zones_alternate_insurance_table[$j] = $zones_indemnity_table[$i];
$zones_alternate_insurance_table[$j+1] = $zones_alternate_insurance_table[1];
}
if ($shipping_weight > $zones_insurance_threshold1) {
for ($j=0; (($j < $insursize) && ($zones_insurance_table[$j] <= $zones_indemnity_table[$i])); $j+=2) {
$zones_insurance_table[$j] = $zones_indemnity_table[$i];
$zones_insurance_table[$j+1] = $zones_insurance_table[1];
}
}
}