skip to Main Content

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

3

Answers


  1. Chosen as BEST ANSWER

    @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'];
    

  2. 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.

    Login or Signup to reply.
  3. 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'];

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search