0

I've been staring at this for some time, but can't figure out what's wrong. First of all my code:

//Show the products information line by line
$item_count = 0 ;
for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) {
    $data2[$i][0] = $order->products[$i]['qty'];

    if (strlen($order->products[$i]['name']) > 40 && strlen($order->products[$i]['name']) < 50){
        $data2[$i][1] = $order->products[$i]['name'];
    } else if (strlen($order->products[$i]['name']) > 50) {
        $data2[$i][1] = substr($order->products[$i]['name'],0,50);
    } else {
        $data2[$i][1] = $order->products[$i]['name'];
    }

    $data2[$i][2] = $order->products[$i]['model'];

    $data2[$i][3] = str_replace('&nbsp;', ' ',$currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value']));

    // Add to $data2 if needed (adjust/renumber subsequent array keys!):

    // For VAT purposes:
    // Check if product is an 'electronic service'. If so, determine the customer's country.

    // NOTE (Debug): the comparison of " pov.products_options_values_name = $order->products[$i]['attributes'][$j]['value'] " only holds if the option description is not changed/replaced/deleted.

    if (isset($order->products[$i]['attributes']) && (($k = sizeof($order->products[$i]['attributes'])) > 0)) {
        for ($j = 0; $j < $k; $j++) {
            $virtual_check_query = tep_db_query("select count(*) as total from " . TABLE_PRODUCTS_ATTRIBUTES . " pa, " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad, " . TABLE_PRODUCTS_OPTIONS_VALUES . " pov where pa.products_id = '" . $order->products[$i]['id'] . "' and pov.products_options_values_name = '" . $order->products[$i]['attributes'][$j]['value'] . "' and pa.products_attributes_id = pad.products_attributes_id");
            $virtual_check = tep_db_fetch_array($virtual_check_query);
            if ($virtual_check['total'] > 0) {
                $product_type_check = 'virtual';
                $order_type_check = 'virtual or mixed';
                break;
            }
        }
    }

    if ($product_type_check == 'virtual') {
        if ($customer_country == 'home country') {
            $data2[$i][4] = str_replace('&nbsp;', ' ',tep_display_tax_value($order->products[$i]['tax']) . '%');
        } elseif ($customer_country == 'eu country') {
            $data2[$i][4] = '***';
        } else {
            $data2[$i][4] = str_replace('&nbsp;', ' ',tep_display_tax_value($order->products[$i]['tax']) . '%');
        }
    } else {
        $data2[$i][4] = str_replace('&nbsp;', ' ',tep_display_tax_value($order->products[$i]['tax']) . '%');
    }

    unset($product_type_check);

    //      $data2[$i][3] = str_replace('&nbsp;', ' ',$currencies->format($order->products[$i]['final_price'], true, $order->info['currency'], $order->info['currency_value']));

    // Add to $data2 if needed (adjust/renumber subsequent array keys!):
    //      $data2[$i][5] = str_replace('&nbsp;', ' ',$currencies->format(tep_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']), true, $order->info['currency'], $order->info['currency_value']));

    $data2[$i][5] = str_replace('&nbsp;', ' ',$currencies->format($order->products[$i]['final_price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value'])) ;

    // Add to $data2 if needed (adjust/renumber subsequent array keys!):
    //      $data2[$i][5] = str_replace('&nbsp;', ' ',$currencies->format(tep_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']) * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']));


    // Show the products attributes
    $data3 = array();

    //get attribs
    if (isset($order->products[$i]['attributes']) && (($z = sizeof($order->products[$i]['attributes'])) > 0)) {
        $attribute_line = 'true';
        for ($m = 0; $m < $z; $m++) {
            if ($order->products[$i]['attributes'][$m]['price'] != '0') {
                if (strlen('- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value'] . ' (' . $order->products[$i]['attributes'][$m]['prefix'] . $currencies->format($order->products[$i]['attributes'][$m]['price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) . ')') > 50) {
                    $data3[$i][$m][1] = substr('- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value'],0,40) . ' (' . $order->products[$i]['attributes'][$m]['prefix'] . $currencies->format($order->products[$i]['attributes'][$m]['price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) . ')';
                } else {
                    $data3[$i][$m][1] = '- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value'] . ' (' . $order->products[$i]['attributes'][$m]['prefix'] . $currencies->format($order->products[$i]['attributes'][$m]['price'] * $order->products[$i]['qty'], true, $order->info['currency'], $order->info['currency_value']) . ')' ;
                }
            } else {
                if (strlen('- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value']) > 50) {
                    $data3[$i][$m][1] = substr('- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value'],0,50);
                } else {
                    //        $data3[$i][$m][1] = '- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value'];
                    $data3[$i][$m][1] = '- ' . $order->products[$i]['attributes'][$m]['value'];
                }
            }
        }
    }
}

The code above is supposed to:

  • Put the general product data into the array $data2

  • Put the attributes of each product (which can be more than one) into the array $data3

The array $order->products contains the following data:

Array (

[0] => Array ( 
[qty] => 1 
[id] => 4 
[name] => Product A
[model] => 
[tax] => 21.0000 
[price] => 19.9900 
[final_price] => 19.9900 
[attributes] => Array ( 
[0] => Array ( 
[option] => Type 
[value] => X 
[prefix] => + 
[price] => 0.0000 
) 
) 
) 

[1] => Array ( 
[qty] => 1 
[id] => 4 
[name] => Product A
[model] => 
[tax] => 21.0000 
[price] => 19.9900 
[final_price] => 19.9900 
[attributes] => Array ( 
[0] => Array ( 
[option] => Type 
[value] => Y
[prefix] => 
[price] => 0.0000 
) 
) 
) 
)

The code enters the following data in the array $data3:

Array ( 
[1] => Array (
[0] => Array (
[1] => - Y
) 
) 
) 

This means that the attributes of the first product (Product A with key 0 in the $order->products array is missing!

My gut feeling tells me that the code has moved already moved through the $order->products array before executing the 'Show the products attributes' section of the code.

The code is based on this snippet taken from checkout_confirmation.php (osCommerce):

for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
echo '          <tr>' . "\n" .
 '            <td class="infoBoxMargin">' . tep_draw_separator('pixel_trans.gif', '10', '1') . '</td>' . "\n" .
     '            <td class="main" align="left" valign="top" width="10%">' . $order->products[$i]['qty'] . '&nbsp;x</td>' . "\n" .
     '            <td class="main" align="left" valign="top" width="60%">' . $order->products[$i]['name'];

if (STOCK_CHECK == 'true') {
  echo tep_check_stock($order->products[$i]['id'], $order->products[$i]['qty']);
}

if ( (isset($order->products[$i]['attributes'])) && (sizeof($order->products[$i]['attributes']) > 0) ) {
  for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
echo '<br /><nobr><small>&nbsp;<i> - ' . $order->products[$i]['attributes'][$j]['option'] . ': ' . $order->products[$i]['attributes'][$j]['value'] . '</i></small></nobr>';
  }
}

Can anyone explain to me where things go wrong?

Kind regards,

Dennis

4
  • Well for one thing you're missing a } somewhere (for the for loop?), the code in your first sample won't run. Commented Feb 15, 2015 at 19:08
  • 1
    Why do you have price defined twice for each product? Commented Feb 15, 2015 at 19:30
  • @Gragmonkey. You're right about the missing }. You can add that at the end of the code. Your second question: The array contains 2 versions of the same product (A). Prices are the same in my example, but could be different. Commented Feb 15, 2015 at 19:44
  • I meant that the attributes contain a price that is always zero, which is not the same as the price farther up the array. Commented Feb 15, 2015 at 19:50

3 Answers 3

1

Using your sample data for $order->products, $order->products[$i]['attributes'][$m]['price'] is always zero. Also, since strlen('- ' . $order->products[$i]['attributes'][$m]['option'] . ': ' . $order->products[$i]['attributes'][$m]['value']) is always <50, the only code in the //get attribs section that executes with your sample data is $data3[$i][$m][1] = '- ' . $order->products[$i]['attributes'][$m]['value']; ... which is why $data3[$i][$m][1] is the only value that gets populated.

However, assuming your two missing } belong at the end, then $data3 is getting overwritten for every value of $i on account of wher $data3 = array(); is located.

If you move $data3 = array(); to the top of your code (before the for loop), you'll at least no longer overwrite the values in $data3 for each version of your product.

If you want $data3 to contain a copy of every attribute, then try changing $data3[$i][$m][1] = '- ' . $order->products[$i]['attributes'][$m]['value']; to $data3[$i][$m] = $order->products[$i]['attributes'];

Sign up to request clarification or add additional context in comments.

Comments

1

@lazy.lizard

It can be that easy ... if you know what you're doing!

The code now starts with:

$data2=array();
$data3 = array();

//Show the products information line by line
$item_count = 0 ;
for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) {

$data2[$i][0] = $order->products[$i]['qty'];

1 Comment

If lazy.lizard's answer was helpful, don't forget to upvote it. If it solved your problem, then mark it as the accepted answer.
0

Dealing with osCommerce code for many years I have to say, that there are lots of wierd code and if you are not for long with it, you better migrate to something new, thay doesn't use register_globals al least. Another reason to migrate is that there's no MVC model - you always see mixed php code, html layout and sql queries, especially in admin section. Another important reason for migration is tables structure, or more precisely, lack or wrong indexes.

As for me, I've completely rewritten lots of code, including totally new product class and products attributes. Now, for example, I use product object everywhere, including products list in category, shoping cart, wishlist, etc. Believe me, I don't have a headache with separate sql queries that get different products' data.

Now to you question. I suppose that problem is here:

$data3 = array();

Each time you loop $order->products your variable is set to empty array. Thus try to define it before you start iterating $order->products. For example:

$data3 = array();
for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) {
// your code
}

and don't forget to remove $data3 = array(); from the loop.

Hope this helps.

Good luck.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.