Seditio Source
Root |
./othercms/ips_4.3.4/applications/nexus/sources/Money/Money.php
<?php
/**
 * @brief        Money Object
 * @author        <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
 * @copyright    (c) Invision Power Services, Inc.
 * @license        https://www.invisioncommunity.com/legal/standards/
 * @package        Invision Community
 * @subpackage    Nexus
 * @since        11 Feb 2014
 */

namespace IPS\nexus;

/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
   
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
    exit;
}

/**
 * Money Object
 */
class _Money
{    
   
/**
     * Get available currencies
     *
     * @return    array
     */
   
public static function currencies()
    {
        if (
$currencies = json_decode( \IPS\Settings::i()->nexus_currency, TRUE ) )
        {
            return
array_keys( $currencies );
        }
        else
        {
            return array( \
IPS\Settings::i()->nexus_currency );
        }
    }
   
   
/**
     * Get the number of decimal points used for a currency
     *
     * @param    string    $currency    Currency code
     * @return    int
     */
   
public static function numberOfDecimalsForCurrency( $currency )
    {
        switch (
$currency )
        {
            case
'CLF':
                return
4;
               
            case
'BHD':
            case
'IQD':
            case
'JOD':
            case
'KWD':
            case
'LYD':
            case
'OMR':
            case
'TND':
                return
3;
               
            case
'MGA':
            case
'MRO':
                return
1;
               
            case
'BIF':
            case
'BYR':
            case
'CLP':
            case
'CVE':
            case
'DJF':
            case
'GNF':
            case
'ISK':
            case
'JPY':
            case
'KMF':
            case
'KRW':
            case
'PYG':
            case
'RWF':
            case
'UGX':
            case
'UYI':
            case
'VND':
            case
'VUV':
            case
'XAF':
            case
'XOF':
            case
'XPF':
                return
0;
           
            default:
                return
2;
        }
    }
       
   
/**
     * @brief    Amount
     */
   
public $amount;
   
   
/**
     * @brief    Currency
     */
   
public $currency;
   
   
/**
     * @brief    Number of decimal points
     */
   
protected $numberOfDecimalPlaces = 2;
   
   
/**
     * Contructor
     *
     * @param    mixed    $amount        Amount
     * @param    string    $currency    Currency code
     * @return    void
     */
   
public function __construct( $amount, $currency )
    {
       
$this->currency = $currency;
       
$this->numberOfDecimalPlaces = static::numberOfDecimalsForCurrency( $currency );
       
        if ( !(
$amount instanceof \IPS\Math\Number ) )
        {
            if (
is_string( $amount ) )
            {
               
$amount = floatval( $amount );
            }
           
$amount = new \IPS\Math\Number( number_format( $amount, $this->numberOfDecimalPlaces, '.', '' ) );
        }
       
       
$this->amount = $amount->round( $this->numberOfDecimalPlaces );
    }
       
   
/**
     * Amount as string (not formatted, not locale aware)
     * Used for gateways where, for example, (float) 10.5 is not acceptable, and (string) "10.50" is required
     *
     * @return    \IPS\nexus\Money
     */
   
public function amountAsString()
    {
        return
sprintf( "%01." . $this->numberOfDecimalPlaces . "F", (string) $this->amount );
    }
   
   
/**
     * To string
     *
     * @return    string
     */
   
public function __toString()
    {
        return
$this->toString( \IPS\Member::loggedIn()->language() );
    }
   
   
/**
     * To string for language
     *
     * @param    \IPS\Lang    $language    The language to use
     * @return    string
     */
   
public function toString( \IPS\Lang $language )
    {                
       
/* If this currency matches the locale the user is using, and money_format is supported (Windows doesn't support it), use that */
       
if ( function_exists( 'money_format' ) and trim( $language->locale['int_curr_symbol'] ) === $this->currency )
        {
           
/* We need to make sure the locale is correct */
           
$currentLocale = setlocale( LC_ALL, '0' );
           
$language->setLocale();
           
           
/* Get the value to use */
           
$return = money_format( '%n', (string) $this->amount );
           
           
/* Then put the locale back */
           
\IPS\Lang::restoreLocale( $currentLocale );
           
           
/* And return */
           
return $return;
        }
               
       
/* If it matches any of the installed languages, we can do something with the locale data */
       
foreach ( \IPS\Lang::languages() as $lang )
        {
            if ( isset(
$lang->locale['int_curr_symbol'] ) AND trim( $lang->locale['int_curr_symbol'] ) === $this->currency )
            {
               
$currencySymbol = $lang->convertString( $lang->locale['currency_symbol'] );
               
$currencySymbolPreceeds = $this->amount->isPositive() ? $lang->locale['p_cs_precedes'] : $lang->locale['n_cs_precedes'];
               
$spaceBetweenCurrencySymbolAndAmount = ( $this->amount->isPositive() ? $lang->locale['p_sep_by_space'] : $lang->locale['n_sep_by_space'] ) ? ' ' : '';
               
$amount = number_format( (string) $this->amount, $lang->locale['frac_digits'], $lang->locale['mon_decimal_point'], $lang->locale['mon_thousands_sep'] );
               
               
$positiveNegativeSymbol = $this->amount->isPositive() ? $lang->locale['positive_sign'] : $lang->locale['negative_sign'];
                if (
$positiveNegativeSymbol )
                {
                   
$positiveNegativeSymbolFormat = $this->amount->isPositive() ? $lang->locale['p_sign_posn'] : $lang->locale['n_sign_posn'];
                   
$positiveNegativeSymbolFormatLength = \strlen( $positiveNegativeSymbolFormat );
                    for (
$i=0; $i < $positiveNegativeSymbolFormatLength; $i++ )
                    {
                        switch (
$positiveNegativeSymbolFormat[ $i ] )
                        {
                            case
0:
                                if (
$currencySymbolPreceeds )
                                {
                                   
$currencySymbol = "({$currencySymbol}";
                                   
$amount = "{$amount})";
                                }
                                else
                                {
                                   
$currencySymbol = "{$currencySymbol})";
                                   
$amount = "({$amount}";
                                }
                                break;
                            case
1:
                                if (
$currencySymbolPreceeds )
                                {
                                   
$currencySymbol = "{$positiveNegativeSymbol}{$currencySymbol}";
                                }
                                else
                                {
                                   
$amount = "{$positiveNegativeSymbol}{$amount}";
                                }
                                break;
                            case
2:
                                if (
$currencySymbolPreceeds )
                                {
                                   
$amount = "{$amount}{$positiveNegativeSymbol}";
                                }
                                else
                                {
                                   
$currencySymbol = "{$currencySymbol}{$positiveNegativeSymbol}";
                                }
                                break;
                            case
3:
                               
$currencySymbol = ( $positiveNegativeSymbol . $currencySymbol );
                                break;
                            case
4:
                               
$currencySymbol = ( $currencySymbol . $positiveNegativeSymbol );
                                break;
                        }
                    }
                }
               
                return (
$currencySymbolPreceeds ? ( $currencySymbol . $spaceBetweenCurrencySymbolAndAmount . $amount ) : ( $amount . $spaceBetweenCurrencySymbolAndAmount . $currencySymbol ) );
            }
        }

       
/* And if all else fails, just use the currency code */
       
return number_format( (string) $this->amount, static::numberOfDecimalsForCurrency( $this->currency ) ) . " {$this->currency}";
    }
   
   
/**
     * Get output for API
     *
     * @param    \IPS\Member|NULL    $authorizedMember    The member making the API request or NULL for API Key / client_credentials
     * @return    array
     * @apiresponse    string    currency    The currency code (e.g. 'USD')
     * @apiresponse    string    amount        The amount
     */
   
public function apiOutput( \IPS\Member $authorizedMember = NULL )
    {
        return array(
           
'currency'    => $this->currency,
           
'amount'    => $this->amountAsString(),
        );
    }
}