Latest News: (loading..)

Archived

This topic is now archived and is closed to further replies.

D-BlooD

PHP 5.3 number_format() in currencies.php

9 posts in this topic

My host has updated to PHP 5.3 and of course osc broke ;)

 

I have sorted out most of the problems I was having but i am stuck with this last thing (i hope its the last thing now).

 

Warning: number_format() expects parameter 2 to be long, string given in /customers/xxxxxxx.xx/xxxxxxx.xx/httpd.www/includes/classes/currencies.php on line 42

 

<?php
/*
 $Id: currencies.php 1803 2008-01-11 18:16:37Z hpdl $

 osCommerce, Open Source E-Commerce Solutions
 http://www.oscommerce.com

 Copyright (c) 2008 osCommerce

 Released under the GNU General Public License
*/

////
// Class to handle currencies
// TABLES: currencies
 class currencies {
   var $currencies;

// class constructor
   function currencies() {
     $this->currencies = array();
     $currencies_query = tep_db_query("select code, title, symbol_left, symbol_right, decimal_point, thousands_point, decimal_places, value from " . TABLE_CURRENCIES);
     while ($currencies = tep_db_fetch_array($currencies_query)) {
       $this->currencies[$currencies['code']] = array('title' => $currencies['title'],
                                                      'symbol_left' => $currencies['symbol_left'],
                                                      'symbol_right' => $currencies['symbol_right'],
                                                      'decimal_point' => $currencies['decimal_point'],
                                                      'thousands_point' => $currencies['thousands_point'],
                                                      'decimal_places' => $currencies['decimal_places'],
                                                      'value' => $currencies['value']);
     }
   }

// class methods
   function format($number, $calculate_currency_value = true, $currency_type = '', $currency_value = '') {
     global $currency;

     if (empty($currency_type)) $currency_type = $currency;

     if ($calculate_currency_value == true) {
       $rate = (tep_not_null($currency_value)) ? $currency_value : $this->currencies[$currency_type]['value'];
       $format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number * $rate, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
     } else {
       $format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
     }

     return $format_string;
   }

   function calculate_price($products_price, $products_tax, $quantity = 1) {
     global $currency;

     return tep_round(tep_add_tax($products_price, $products_tax), $this->currencies[$currency]['decimal_places']) * $quantity;
   }

   function is_set($code) {
     if (isset($this->currencies[$code]) && tep_not_null($this->currencies[$code])) {
       return true;
     } else {
       return false;
     }
   }

   function get_value($code) {
     return $this->currencies[$code]['value'];
   }

   function get_decimal_places($code) {
     return $this->currencies[$code]['decimal_places'];
   }

   function display_price($products_price, $products_tax, $quantity = 1) {
     return $this->format($this->calculate_price($products_price, $products_tax, $quantity));
   }
 }
?>

 

Anyone know how to solve this one? Tried searching for it both on google and here but nothing came up ;).

 

--

D-BlooD

Share this post


Link to post
Share on other sites

BACKUP THE FILE FIRST.

 

Then change this code:

 

  if ($calculate_currency_value == true) {
   $rate = (tep_not_null($currency_value)) ? $currency_value : $this->currencies[$currency_type]['value'];
   $format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number * $rate, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
 } else {
   $format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number, $this->currencies[$currency_type]['decimal_places']), $this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
 }

to:

 

  if ($calculate_currency_value == true) {
   $rate = (tep_not_null($currency_value)) ? $currency_value : $this->currencies[$currency_type]['value'];
   $format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number * $rate, $this->currencies[$currency_type]['decimal_places']), (int)$this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
 } else {
   $format_string = $this->currencies[$currency_type]['symbol_left'] . number_format(tep_round($number, $this->currencies[$currency_type]['decimal_places']), (int)$this->currencies[$currency_type]['decimal_places'], $this->currencies[$currency_type]['decimal_point'], $this->currencies[$currency_type]['thousands_point']) . $this->currencies[$currency_type]['symbol_right'];
 }

All you have to do is "type cast" the variable in the right fashion.

:thumbsup:

Andy H likes this

Share this post


Link to post
Share on other sites

Thanks, germ.

 

This problem has had me searching for a solution for hours. It seems my hosting company recently updated to PHP 5.2.17. I'd seen this page but I wasn't sure it was relevant because I wasn't seeing any PHP warning errors (despite having error_reporting = E_ALL in php.ini). I'd tried the solution above, but I'd edited the include file for the general catalog folder, not the admin one. Now I've edited the right file it works - just type cast parameter two to (int) in both the lines germ points out above.

 

FWIW (and to help others find this page), the message osCommerce was showing me was:

 

 

The exchange rate for UK Pound (GBP) was updated successfully via oanda.

Warning: The primary exchange rate server (oanda) failed for Euro (EUR) - trying the secondary exchange rate server.

Error: The exchange rate for Euro (EUR) was not updated via xe. Is it a valid currency code?

 

 

Though sometimes, it would give me this instead:

 

 

Warning: The primary exchange rate server (oanda) failed for UK Pound (GBP) - trying the secondary exchange rate server.

Error: The exchange rate for UK Pound (GBP) was not updated via xe. Is it a valid currency code?

Warning: The primary exchange rate server (oanda) failed for Euro (EUR) - trying the secondary exchange rate server.

Error: The exchange rate for Euro (EUR) was not updated via xe. Is it a valid currency code?

 

 

- UK Pound (GBP) is my default currency.

Share this post


Link to post
Share on other sites

Actually, I would have to strongly disagree with germ's "fix". While it will certainly suppress the error message, by forcing the number of decimal places to a number for sure (possibly 0), it doesn't solve the original problem. Which is... for your currency, for some reason it has something setting the currency decimal places to a non-integer value. Maybe the numeric value that's supposed to be there (e.g., '2' for dollars) has been corrupted and replaced by something else, or garbage has been appended to the value string. The proper fix is to find the currency table in the database ('currencies'), look at the currency entry of interest, and see what the 8th field ('decimal_places') is (should be '2' for US dollar) and fix it if it is not an integer of 0 or larger.

 

It may have well been corrupted for a long time, and PHP 5.3 is stricter about using nonnumeric values than earlier PHP versions.

Share this post


Link to post
Share on other sites

Hi Jim:

 

You are genius, I used your 'TYPE CAST" fixed that stupid annoying "currency.php" problem on my homepage.

 

However, now I still get some problems on the whole website working back in noraml.....

 

1) I got this on my Admin Page: " Deprecated: Function eregi() is deprecated in /home/content/c/h/o/choleholdings/html/shangwong/includes/classes/language.php on line 87 "

 

2) When I clicked on all catagory contents on my homepage to see that individual items in details, but always it goes back to the homepage. Why was that ??

 

Appreciated your help.

Share this post


Link to post
Share on other sites

The solution is core php 5.3 update and not type casting, but somehow you can save "p" in decimal places because the field type is "char". I agree with @@MrPhil. The default should be "0" zero value and prohibited using characters. The suggested fix rather maybe:

 

 

ALTER TABLE `currencies` CHANGE `decimal_places` `decimal_places` TINYINT( 1 ) NULL DEFAULT NULL

 

 

The space " " is not equal with Null or "0" zero value!

Share this post


Link to post
Share on other sites

I don't see any place that 'decimal_places' is used as anything but a number (an integer), so I'd be curious to know if anyone could explain why it's declared char(1) instead of some small integer. Was it expected that some sort of special formats might be allowed in the future, to be specified with letters? It also appears that NULL is allowed as a value. If it doesn't get treated as a 0, that could be a problem.

Share this post


Link to post
Share on other sites