localeNameFormatDefault = empty($sugar_config['locale_name_format_default']) ? 's f l' : $sugar_config['default_name_format']; $this->loadCurrencies(); } /** * returns an array of Sugar Config defaults that are determined by locale settings * @return array */ function getLocaleConfigDefaults() { $coreDefaults = array( 'currency' => '', 'datef' => 'm/d/Y', 'timef' => 'H:i', 'default_currency_significant_digits' => 2, 'default_currency_symbol' => '$', 'default_export_charset' => $this->default_export_charset, 'default_locale_name_format' => 's f l', 'default_number_grouping_seperator' => ',', 'default_decimal_seperator' => '.', 'export_delimiter' => ',', 'default_email_charset' => $this->default_email_charset, ); return $coreDefaults; } /** * abstraction of precedence * @param string prefName Name of preference to retrieve based on overrides * @param object user User in focus, default null (current_user) * @return string pref Most significant preference */ function getPrecedentPreference($prefName, $user=null, $sugarConfigPrefName = '') { global $current_user; global $sugar_config; $userPref = ''; $coreDefaults = $this->getLocaleConfigDefaults(); $pref = isset($coreDefaults[$prefName]) ? $coreDefaults[$prefName] : ''; // defaults, even before config.php if($user != null) { $userPref = $user->getPreference($prefName); } elseif(!empty($current_user)) { $userPref = $current_user->getPreference($prefName); } // Bug 39171 - If we are asking for default_email_charset, check in emailSettings['defaultOutboundCharset'] as well if ( $prefName == 'default_email_charset' ) { if($user != null) { $emailSettings = $user->getPreference('emailSettings', 'Emails'); } elseif(!empty($current_user)) { $emailSettings = $current_user->getPreference('emailSettings', 'Emails'); } if ( isset($emailSettings['defaultOutboundCharset']) ) { $userPref = $emailSettings['defaultOutboundCharset']; } } // set fallback defaults defined in this class if(isset($this->$prefName)) { $pref = $this->$prefName; } //rrs: 33086 - give the ability to pass in the preference name as stored in $sugar_config. if(!empty($sugarConfigPrefName)){ $prefName = $sugarConfigPrefName; } // cn: 9549 empty() call on a value of 0 (0 significant digits) resulted in a false-positive. changing to "isset()" $pref = (!isset($sugar_config[$prefName]) || (empty($sugar_config[$prefName]) && $sugar_config[$prefName] !== '0')) ? $pref : $sugar_config[$prefName]; $pref = (empty($userPref) && $userPref !== '0') ? $pref : $userPref; return $pref; } /////////////////////////////////////////////////////////////////////////// //// CURRENCY HANDLING /** * wrapper for whatever currency system we implement */ function loadCurrencies() { // doing it dirty here global $db; global $sugar_config; if(empty($db)) { return array(); } $load = sugar_cache_retrieve('currency_list'); if ( !is_array($load) ) { // load default from config.php $this->currencies['-99'] = array( 'name' => $sugar_config['default_currency_name'], 'symbol' => $sugar_config['default_currency_symbol'], 'conversion_rate' => 1 ); $q = "SELECT id, name, symbol, conversion_rate FROM currencies WHERE status = 'Active' and deleted = 0"; $r = $db->query($q); while($a = $db->fetchByAssoc($r)) { $load = array(); $load['name'] = $a['name']; $load['symbol'] = $a['symbol']; $load['conversion_rate'] = $a['conversion_rate']; $this->currencies[$a['id']] = $load; } sugar_cache_put('currency_list',$this->currencies); } else { $this->currencies = $load; } } /** * getter for currencies array * @return array $this->currencies returns array( id => array(name => X, etc */ function getCurrencies() { return $this->currencies; } /** * retrieves default OOTB currencies for sugar_config and installer. * @return array ret Array of default currencies keyed by ISO4217 code */ function getDefaultCurrencies() { $ret = array( 'AUD' => array( 'name' => 'Australian Dollars', 'iso4217' => 'AUD', 'symbol' => '$'), 'BRL' => array( 'name' => 'Brazilian Reais', 'iso4217' => 'BRL', 'symbol' => 'R$'), 'GBP' => array( 'name' => 'British Pounds', 'iso4217' => 'GBP', 'symbol' => '£'), 'CAD' => array( 'name' => 'Canadian Dollars', 'iso4217' => 'CAD', 'symbol' => '$'), 'CNY' => array( 'name' => 'Chinese Yuan', 'iso4217' => 'CNY', 'symbol' => '¥'), 'EUR' => array( 'name' => 'Euro', 'iso4217' => 'EUR', 'symbol' => '€'), 'HKD' => array( 'name' => 'Hong Kong Dollars', 'iso4217' => 'HKD', 'symbol' => '$'), 'INR' => array( 'name' => 'Indian Rupees', 'iso4217' => 'INR', 'symbol' => '₨'), 'KRW' => array( 'name' => 'Korean Won', 'iso4217' => 'KRW', 'symbol' => '₩'), 'YEN' => array( 'name' => 'Japanese Yen', 'iso4217' => 'JPY', 'symbol' => '¥'), 'MXM' => array( 'name' => 'Mexican Pesos', 'iso4217' => 'MXM', 'symbol' => '$'), 'SGD' => array( 'name' => 'Singaporean Dollars', 'iso4217' => 'SGD', 'symbol' => '$'), 'CHF' => array( 'name' => 'Swiss Franc', 'iso4217' => 'CHF', 'symbol' => 'SFr.'), 'THB' => array( 'name' => 'Thai Baht', 'iso4217' => 'THB', 'symbol' => '฿'), 'USD' => array( 'name' => 'US Dollars', 'iso4217' => 'USD', 'symbol' => '$'), ); return $ret; } //// END CURRENCY HANDLING /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //// CHARSET TRANSLATION /** * returns a mod|app_strings array in the target charset * @param array strings $mod_string, et.al. * @param string charset Target charset * @return array Translated string pack */ function translateStringPack($strings, $charset) { // handle recursive foreach($strings as $k => $v) { if(is_array($v)) { $strings[$k] = $this->translateStringPack($v, $charset); } else { $strings[$k] = $this->translateCharset($v, 'UTF-8', $charset); } } ksort($strings); return $strings; } /** * translates the passed variable for email sending (export) * @param mixed the var (array or string) to translate * @return mixed the translated variable */ function translateForEmail($var) { if(is_array($var)) { foreach($var as $k => $v) { $var[$k] = $this->translateForEmail($v); } return $var; } elseif(!empty($var)) { return $this->translateCharset($var, 'UTF-8', $this->getOutboundEmailCharset()); } } /** * prepares a bean for export by translating any text fields into the export * character set * @param bean object A SugarBean * @return bean object The bean with translated strings */ function prepBeanForExport($bean) { foreach($bean->field_defs as $k => $field) { $bean->$k = $this->translateCharset($bean->$k, 'UTF-8', $this->getExportCharset()); } return $bean; } /** * translates a character set from one encoding to another encoding * @param string string the string to be translated * @param string fromCharset the charset the string is currently in * @param string toCharset the charset to translate into (defaults to UTF-8) * @return string the translated string */ function translateCharset($string, $fromCharset, $toCharset='UTF-8') { $GLOBALS['log']->debug("Localization: translating [ {$string} ] into {$toCharset}"); if(function_exists('mb_convert_encoding')) { return mb_convert_encoding($string, $toCharset, $fromCharset); } elseif(function_exists('iconv')) { // iconv is flakey return iconv($fromCharset, $toCharset, $string); } else { return $string; } // end else clause } /** * translates a character set from one to another, and the into MIME-header friendly format */ function translateCharsetMIME($string, $fromCharset, $toCharset='UTF-8', $encoding="Q") { $previousEncoding = mb_internal_encoding(); mb_internal_encoding($toCharset); $result = mb_encode_mimeheader($string, $toCharset, $encoding); mb_internal_encoding($previousEncoding); return $result; } function normalizeCharset($charset) { $charset = strtolower(preg_replace("/[\-\_]*/", "", $charset)); return $charset; } /** * returns an array of charsets with keys for available translations; appropriate for get_select_options_with_id() */ function getCharsetSelect() { //jc:12293 - the "labels" or "human-readable" representations of the various charsets //should be translatable $translated = array(); foreach($this->availableCharsets as $key) { //$translated[$key] = translate($value); $translated[$key] = translate($key); } return $translated; //end:12293 } /** * returns the charset preferred in descending order: User, Sugar Config, DEFAULT * @param string charset to override ALL, pass a valid charset here * @return string charset the chosen character set */ function getExportCharset($charset='', $user=null) { $charset = $this->getPrecedentPreference('default_export_charset', $user); return $charset; } /** * returns the charset preferred in descending order: User, Sugar Config, DEFAULT * @return string charset the chosen character set */ function getOutboundEmailCharset($user=null) { $charset = $this->getPrecedentPreference('default_email_charset', $user); return $charset; } //// END CHARSET TRANSLATION /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //// NUMBER DISPLAY FORMATTING CODE function getDecimalSeparator($user=null) { $dec = $this->getPrecedentPreference('default_decimal_separator', $user); return $dec; } function getNumberGroupingSeparator($user=null) { $sep = $this->getPrecedentPreference('default_number_grouping_seperator', $user); return $sep; } function getPrecision($user=null) { $precision = $this->getPrecedentPreference('default_currency_significant_digits', $user); return $precision; } function getCurrencySymbol($user=null) { $dec = $this->getPrecedentPreference('default_currency_symbol', $user); return $dec; } /** * returns a number formatted by user preference or system default * @param string number Number to be formatted and returned * @param string currencySymbol Currency symbol if override is necessary * @param bool is_currency Flag to also return the currency symbol * @return string Formatted number */ function getLocaleFormattedNumber($number, $currencySymbol='', $is_currency=true, $user=null) { $fnum = $number; $majorDigits = ''; $minorDigits = ''; $dec = $this->getDecimalSeparator($user); $thou = $this->getNumberGroupingSeparator($user); $precision = $this->getPrecision($user); $symbol = empty($currencySymbol) ? $this->getCurrencySymbol($user) : $currencySymbol; $exNum = explode($dec, $number); // handle grouping if(is_array($exNum) && count($exNum) > 0) { if(strlen($exNum[0]) > 3) { $offset = strlen($exNum[0]) % 3; if($offset > 0) { for($i=0; $i<$offset; $i++) { $majorDigits .= $exNum[0]{$i}; } } $tic = 0; for($i=$offset; $i 0) { // we toss the minor digits otherwise if(is_array($exNum) && isset($exNum[1])) { } } if($is_currency) { $fnum = $symbol.$fnum; } return $fnum; } /** * returns Javascript to format numbers and currency for ***DISPLAY*** */ function getNumberJs() { $out = << 0) { var strlength = majorDigits.length; if(strlength > 3) { var offset = strlength % 3; // find how many to lead off by for(j=0; j 0) { for(i=0; igetPrecedentPreference('default_locale_name_format', $user); return $returnFormat; } /** * returns formatted name according to $current_user's locale settings * * @param string firstName * @param string lastName * @param string salutation * @param string title * @param string format If a particular format is desired, then pass this optional parameter as a simple string. * sfl is "Salutation FirstName LastName", "l, f s" is "LastName[comma][space]FirstName[space]Salutation" * @param object user object * @param bool returnEmptyStringIfEmpty true if we should return back an empty string rather than a single space * when the formatted name would be blank * @return string formattedName */ function getLocaleFormattedName($firstName, $lastName, $salutationKey='', $title='', $format="", $user=null, $returnEmptyStringIfEmpty = false) { global $current_user; global $app_list_strings; if ( $user == null ) { $user = $current_user; } $salutation = $salutationKey; if(!empty($salutationKey) && !empty($app_list_strings['salutation_dom'][$salutationKey])) { $salutation = (!empty($app_list_strings['salutation_dom'][$salutationKey]) ? $app_list_strings['salutation_dom'][$salutationKey] : $salutationKey); } //check to see if passed in variables are set, if so, then populate array with value, //if not, then populate array with blank '' $names = array(); $names['f'] = (empty($firstName) && $firstName != 0) ? '' : $firstName; $names['l'] = (empty($lastName) && $lastName != 0) ? '' : $lastName; $names['s'] = (empty($salutation) && $salutation != 0) ? '' : $salutation; $names['t'] = (empty($title) && $title != 0) ? '' : $title; //Bug: 39936 - if all of the inputs are empty, then don't try to format the name. $allEmpty = true; foreach($names as $key => $val){ if(!empty($val)){ $allEmpty = false; break; } } if($allEmpty){ return $returnEmptyStringIfEmpty ? '' : ' '; } //end Bug: 39936 if(empty($format)) { $this->localeNameFormat = $this->getLocaleFormatMacro($user); } else { $this->localeNameFormat = $format; } // parse localeNameFormat $formattedName = ''; for($i=0; $ilocaleNameFormat); $i++) { $formattedName .= array_key_exists($this->localeNameFormat{$i}, $names) ? $names[$this->localeNameFormat{$i}] : $this->localeNameFormat{$i}; } $formattedName = trim($formattedName); if (strlen($formattedName)==0) { return $returnEmptyStringIfEmpty ? '' : ' '; } if(strpos($formattedName,',',strlen($formattedName)-1)) { // remove trailing commas $formattedName = substr($formattedName, 0, strlen($formattedName)-1); } return trim($formattedName); } /** * outputs some simple Javascript to show a preview of Name format in "My Account" and "Admin->Localization" * @param string first First Name, use app_strings default if not specified * @param string last Last Name, use app_strings default if not specified * @param string salutation Saluation, use app_strings default if not specified * @return string some Javascript */ function getNameJs($first='', $last='', $salutation='', $title='') { global $app_strings; $salutation = !empty($salutation) ? $salutation : $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION']; $first = !empty($first) ? $first : $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST']; $last = !empty($last) ? $last : $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST']; $title = !empty($title) ? $title : $app_strings['LBL_LOCALE_NAME_EXAMPLE_TITLE']; $ret = " function setPreview() { format = document.getElementById('default_locale_name_format').value; field = document.getElementById('nameTarget'); stuff = new Object(); stuff['s'] = '{$salutation}'; stuff['f'] = '{$first}'; stuff['l'] = '{$last}'; stuff['t'] = '{$title}'; var name = ''; for(i=0; i