Jump to content



Photo
- - - - -

PHP 5.3 number_format() in currencies.php


This topic has been archived. This means that you cannot reply to this topic.
8 replies to this topic

#1   D-BlooD

D-BlooD
  • Members
  • 40 posts

Posted 14 November 2009 - 22:49

My host has updated to PHP 5.3 and of course osc broke /wink.gif' class='bbc_emoticon' alt=';)' />

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 /wink.gif' class='bbc_emoticon' alt=';)' />.

--
D-BlooD

#2   germ

germ
  • Members
  • 13,921 posts

Posted 14 November 2009 - 23:35

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.gif' class='bbc_emoticon' alt=':thumbsup:' />
If I suggest you edit any file(s) make a backup first - I'm not perfect and neither are you.

"Given enough impetus a parallelogramatically shaped projectile can egress a circular orifice."
- Me -

"Headers already sent" - The definitive help

"Cannot redeclare ..." - How to find/fix it

SSL Implementation Help

Like this post? "Like" it again over there >

#3   D-BlooD

D-BlooD
  • Members
  • 40 posts

Posted 15 November 2009 - 09:13

Thank you wherry much /smile.gif' class='bbc_emoticon' alt=':)' /> That fixed it..

--
D-BlooD

#4   Andy H

Andy H
  • Members
  • 13 posts

Posted 27 September 2011 - 23:18

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.

#5   MrPhil

MrPhil
  • Members
  • 5,285 posts

Posted 28 September 2011 - 01:07

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.

Edited by MrPhil, 28 September 2011 - 01:10.


#6   kongngau

kongngau
  • Members
  • 31 posts

Posted 24 August 2012 - 10:08

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.

#7   14steve14

14steve14
  • Members
  • 3,529 posts

Posted 24 August 2012 - 16:40

@kongngau

Have a look here http://addons.oscommerce.com/info/7394 for core file updates for php5.3

There may be other deprecated functions depending on what contributions you have installed.
REMEMBER BACKUP, BACKUP AND BACKUP

Don't take life too seriously. no one gets out alive anyway

#8   Gergely

Gergely

    Action Hero

  • Community Team
  • 1,244 posts

Posted 27 June 2013 - 08:55

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!

Edited by Gergely, 27 June 2013 - 09:07.

some rewrites :-


#9   MrPhil

MrPhil
  • Members
  • 5,285 posts

Posted 29 June 2013 - 16:25

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.