SuiteCRM-Core/include/Localization/Localization.php
Dillon-Brown 75ea167930 Squashed 'public/legacy/' changes from ace35f6573..23d711b703
23d711b703 [Legacy] update install language label
58fe59c8da [Legacy] Dashlet Settings Modal Styling Fixes
b880c34877 [Legacy] User Profile Mobile Styling Fixes
ab33cfc7cf [Legacy] Add acls calculation on legacy list data calls
220bf5b8be [Legacy] Get list of visible modules from module name mapper
a7a0754a2d Fix valid module check
020a5dcb1b [Legacy] add widget acl metadata - update acl config for top widget
89e8f7c0f2 [Legacy] Subpanels Action Button Styling Fixes
6c287af813 remove photo widgets for contacts and leads
4ac8347d61 [Legacy] Admin Release Styling Fixes
3336b10790 Suite8 ChangeLog ModalPopup Styling Fixes
8df8ad992c [Legacy] Add close menu label
1dfdf6a005 [Legacy] Add not module selected label
b234b8a1fe [Legacy] Add parent type ApiBeanMapper
4def7cdfc6 [Legacy] Fix username display for unauthorized users
c9771bd330 [Legacy] DetailView Header Title Overlaps fixes
0a0dd3c2c5 [Legacy] Fix htaccess generation
687d5ea7bd Fix Date Filed for Targets
5f863f4b16 [Legacy] Remove Button Hover Fixes
78672e7a27 [Legacy] Reports footer button removed fixes
4b3a9778e8 [Legacy] Reports Styling Fixes
3ab39b6584 [Legacy] Maps Button Position Fixes
e50f76f3fc [Legacy] Add Tab Dashlet Sapcing Fixes
d2f6433a06 [Legacy] Dashlet Setting Modal Label Fix & Button Fixes
e5137262f7 [Legacy] Activity Stream Post Button Hover color fixes
71d44b7274 [Legacy] Bump version to 8.0.0-rc
abafbc280b [Legacy] Remove license from install app strings
43281fae73 Fix ignore system checks valitation
feab3f0abf [Legacy] Add install labels
b0fc8ac7a6 [Legacy] add new install labels
8fea1b7c7f [Legacy] add install validator class
e4f7648e50 [Legacy] Add Label for Subpanel Edit Line Action
b8ecc0a37e [Legacy] Dashboard Mobile Styling Fixes
7d427720f5 [Legacy] History Subpanel Button Styling Fixes
63d10c40d6 [Legacy] Workflow Stying Fixes
811ad79455 [Legacy] Convert Lead Styling Fixes
01764542a1 [Legacy] Roles Styling Fixes
7ecc573f0e [Legacy] Admin Modules label font fixes
9f13c91e22 [Legacy] HomePage Mobile Fixes
005d1ac949 update legacy handlers to apply new logic considering - base actions - action resolvers - fix url navigation issue in classic view
b3c7a14380 [Legacy] Module framework - move suite 8 module config to legacy
542198ac5c [Legacy] Add support for more metadata on listviewdefs
e3c82fc9ea [Legacy] Add Support for all modules with parent css classes
f2dd774903 [Legacy] Security Group Styling Fixes
b6e5591cc4 [Legacy] Password Management Mobile Fixes
1624fdcfad [Leagcy] Email Settings Fixes
e033259dac [Legacy] Products Modules Buttons fixes
eae8efde52 [Legacy] OAUTH2 Clients and tokens fixes
f90c5f5315 [Legacy] adapt legacy install scripts to work with Suite8 install
d099fac028 [Legacy] add labels for S8 Installer
8be5c78c4c [Legacy] Add widget not found label
eb4449777b [Legacy] Email Action DropDown Styling Fixes
06aff4ce92 SuiteCRM 7.12.0 Release
1cf315c98b Fix BasicSearchResults hit counter
c7458ea520 Update PDF samples for compatibility with new PDF Engine
a2a392f6d3 Update Reports PDF for compatibility with new PDF Engine
575561903b Update PDF Engines for backward compatibility
3ed5326ca1 Deprecate TCPDF
b6c4a4941f Fix TCPDF image scale
d6c47de2f5 Fix TCPDF filename
412fd0d006 Add optional malicious file scanner
f88149fcfe Feature: Allow configuring the Calendar name for the Google Sync via the config.
ae836af690 Fix SearchFormView visible options
5f3545193f Update workflow acceptance test
7c54f0fbc4 SuiteCRM 7.12.0-RC Release
0159e0cd86 Remove unused currency config entries
1c49d879ad Default new MySQL based installs to use utf8mb4
dee7ba0594 Clean up search setting
b9b6aeae3a Cleanup old CSS files
ed59f5f6d9 Add missing admin icons
732e84c6a3 Move Workflow to default as admin function
60dce30854 Update admin panel to improve grouping
6f7524b46a Fix filepath for mPDF class
cdab640886 Add default Engines
f79cc55782 Remove MPDFEngine Test
77d38a259d Add check for MPDF class
59261aac8d Remove PDF_Lib
49fb8525a0 Implement TCPDF

git-subtree-dir: public/legacy
git-subtree-split: 23d711b70345ccf90d7508ce6aa5ddc8fd3dc4dd
2021-11-05 15:19:00 +00:00

890 lines
32 KiB
PHP
Executable file

<?php
/**
*
* SugarCRM Community Edition is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
*
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
* Copyright (C) 2011 - 2018 SalesAgility Ltd.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
*/
if (!defined('sugarEntry') || !sugarEntry) {
die('Not A Valid Entry Point');
}
/**
* Localization manager
* @api
*/
class Localization
{
public $availableCharsets = array(
'BIG-5', //Taiwan and Hong Kong
/*'CP866' // ms-dos Cyrillic */
/*'CP949' //Microsoft Korean */
'CP1251', //MS Cyrillic
'CP1252', //MS Western European & US
'EUC-CN', //Simplified Chinese GB2312
'EUC-JP', //Unix Japanese
'EUC-KR', //Korean
'EUC-TW', //Taiwanese
'ISO-2022-JP', //Japanese
'ISO-2022-KR', //Korean
'ISO-8859-1', //Western European and US
'ISO-8859-2', //Central and Eastern European
'ISO-8859-3', //Latin 3
'ISO-8859-4', //Latin 4
'ISO-8859-5', //Cyrillic
'ISO-8859-6', //Arabic
'ISO-8859-7', //Greek
'ISO-8859-8', //Hebrew
'ISO-8859-9', //Latin 5
'ISO-8859-10', //Latin 6
'ISO-8859-13', //Latin 7
'ISO-8859-14', //Latin 8
'ISO-8859-15', //Latin 9
'KOI8-R', //Cyrillic Russian
'KOI8-U', //Cyrillic Ukranian
'SJIS', //MS Japanese
'UTF-8', //UTF-8
'UTF-16LE', //UTF-16LE
);
public $localeNameFormat;
public $localeNameFormatDefault;
public $default_export_charset = 'UTF-8';
public $default_email_charset = 'UTF-8';
public $currencies = array(); // array loaded with current currencies
public $invalidNameFormatUpgradeFilename = 'upgradeInvalidLocaleNameFormat.php';
/* Charset mappings for iconv */
public $iconvCharsetMap = array(
'KS_C_5601-1987' => 'CP949',
'ISO-8859-8-I' => 'ISO-8859-8'
);
/**
* sole constructor
*/
public function __construct()
{
global $sugar_config;
$this->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
*/
public function getLocaleConfigDefaults()
{
$coreDefaults = array(
'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',
'name_formats' => array(
's f l' => 's f l',
'f l' => 'f l',
's l' => 's l',
'l, s f' => 'l, s f',
'l, f' => 'l, f',
's l, f' => 's l, f',
'l s f' => 'l s f',
'l f s' => 'l f s'
),
'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
*/
public 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
*/
public 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
*/
public 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
*/
public 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' => '¥'
),
'MXN' => array(
'name' => 'Mexican Pesos',
'iso4217' => 'MXN',
'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
*/
public 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
*/
public 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
*/
public function prepBeanForExport($bean)
{
foreach ($bean->field_defs as $k => $field) {
if (is_string($bean->$k)) {
// $bean->$k = $this->translateCharset($bean->$k, 'UTF-8', $this->getExportCharset());
} else {
$bean->$k = '';
}
}
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)
* @param bool forceIconv force using the iconv library instead of mb_string
* @return string the translated string
*/
public function translateCharset($string, $fromCharset, $toCharset = 'UTF-8', $forceIconv = false)
{
$GLOBALS['log']->debug("Localization: translating [{$string}] from {$fromCharset} into {$toCharset}");
// Bug #35413 Function has to use iconv if $fromCharset is not in mb_list_encodings
$isMb = function_exists('mb_convert_encoding') && !$forceIconv;
$isIconv = function_exists('iconv');
if ($isMb == true) {
$fromCharset = strtoupper($fromCharset);
$listEncodings = mb_list_encodings();
$isFound = false;
foreach ($listEncodings as $encoding) {
if (strtoupper($encoding) == $fromCharset) {
$isFound = true;
break;
}
}
$isMb = $isFound;
}
if ($isMb) {
return mb_convert_encoding($string, $toCharset, $fromCharset);
} elseif ($isIconv) {
$newFromCharset = $fromCharset;
if (isset($this->iconvCharsetMap[$fromCharset])) {
$newFromCharset = $this->iconvCharsetMap[$fromCharset];
$GLOBALS['log']->debug("Localization: iconv using charset {$newFromCharset} instead of {$fromCharset}");
}
$newToCharset = $toCharset;
if (isset($this->iconvCharsetMap[$toCharset])) {
$newToCharset = $this->iconvCharsetMap[$toCharset];
$GLOBALS['log']->debug("Localization: iconv using charset {$newToCharset} instead of {$toCharset}");
}
return iconv($newFromCharset, $newToCharset, $string);
}
return $string;
}
/**
* Prefixes the input with a BOM.
*
* @param string $string The string to add a BOM to
* @param string $fromCharset The charset of the input string
* @return string The input string including a BOM
* @throws UnexpectedValueException in case the encoding isn't supported
*/
public function addBOM($string, $fromCharset)
{
$charset = $this->normalizeCharset($fromCharset);
if ($charset === 'utf8') {
return "\xef\xbb\xbf" . $string;
} else if ($charset === 'utf16le') {
return "\xff\xfe" . $string;
} else if ($charset === 'utf16be') {
return "\xfe\xff" . $string;
}
throw new UnexpectedValueException('Encoding not supported: ' . $fromCharset);
}
/**
* translates a character set from one to another, and the into MIME-header friendly format
*/
public function translateCharsetMIME($string, $fromCharset, $toCharset = 'UTF-8', $encoding = "Q")
{
$previousEncoding = mb_internal_encoding();
mb_internal_encoding($fromCharset);
$result = mb_encode_mimeheader($string, $toCharset, $encoding);
mb_internal_encoding($previousEncoding);
return $result;
}
public 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()
*/
public 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
*/
public 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
*/
public function getOutboundEmailCharset($user = null)
{
$charset = $this->getPrecedentPreference('default_email_charset', $user);
return $charset;
}
//// END CHARSET TRANSLATION
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//// NUMBER DISPLAY FORMATTING CODE
public function getDecimalSeparator($user = null)
{
// Bug50887 this is purposefully misspelled as ..._separator to match the way it's defined throughout the app.
$dec = $this->getPrecedentPreference('default_decimal_seperator', $user);
return $dec;
}
public function getNumberGroupingSeparator($user = null)
{
$sep = $this->getPrecedentPreference('default_number_grouping_seperator', $user);
return $sep;
}
public function getPrecision($user = null)
{
$precision = $this->getPrecedentPreference('default_currency_significant_digits', $user);
return $precision;
}
public 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
*/
public 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 < strlen($exNum[0]); $i++) {
if ($tic % 3 == 0 && $i != 0) {
$majorDigits .= $thou; // add separator
}
$majorDigits .= $exNum[0][$i];
$tic++;
}
} else {
$majorDigits = $exNum[0]; // no formatting needed
}
$fnum = $majorDigits;
}
// handle decimals
if ($precision > 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***
*/
public function getNumberJs()
{
$out = <<<JAVASCRIPT
var exampleDigits = '123456789.000000';
// round parameter can be negative for decimal, precision has to be postive
function formatNumber(n, sep, dec, precision) {
var majorDigits;
var minorDigits;
var formattedMajor = '';
var formattedMinor = '';
var nArray = n.split('.');
majorDigits = nArray[0];
if (nArray.length < 2) {
minorDigits = 0;
} else {
minorDigits = nArray[1];
}
// handle grouping
if (sep.length > 0) {
var strlength = majorDigits.length;
if (strlength > 3) {
var offset = strlength % 3; // find how many to lead off by
for (j = 0; j < offset; j++) {
formattedMajor += majorDigits[j];
}
tic = 0;
for (i = offset; i < strlength; i++) {
if (tic % 3 == 0 && i != 0)
formattedMajor += sep;
formattedMajor += majorDigits.substr(i,1);
tic++;
}
}
} else {
formattedMajor = majorDigits; // no grouping marker
}
// handle decimal precision
if (precision > 0) {
for (i = 0; i < precision; i++) {
if (minorDigits[i] != undefined) {
formattedMinor += minorDigits[i];
} else {
formattedMinor += '0';
}
}
} else {
// we're just returning the major digits, no decimal marker
dec = ''; // just in case
}
return formattedMajor + dec + formattedMinor;
}
function setSigDigits() {
var sym = document.getElementById('symbol').value;
var thou = document.getElementById('default_number_grouping_seperator').value;
var dec = document.getElementById('default_decimal_seperator').value;
var precision = document.getElementById('sigDigits').value;
//umber(n, num_grp_sep, dec_sep, round, precision)
var newNumber = sym + formatNumber(exampleDigits, thou, dec, precision, precision);
document.getElementById('sigDigitsExample').value = newNumber;
}
JAVASCRIPT;
return $out;
}
//// END NUMBER DISPLAY FORMATTING CODE
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//// NAME DISPLAY FORMATTING CODE
/**
* get's the Name format macro string, preferring $current_user
* @return string format Name Format macro for locale
*/
public function getLocaleFormatMacro($user = null)
{
$returnFormat = $this->getPrecedentPreference('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
*/
public 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; $i < strlen($this->localeNameFormat); $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
*/
public 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 = <<<JAVASCRIPT
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 < format.length; i++) {
if (stuff[format.substr(i,1)] != undefined) {
name += stuff[format.substr(i,1)];
} else {
name += format.substr(i,1);
}
}
field.value = name;
}
JAVASCRIPT;
return $ret;
}
/**
* Checks to see that the characters in $name_format are allowed: s, f, l, space/tab or punctuation
* @param $name_format
* @return bool
*/
public function isAllowedNameFormat($name_format)
{
// will result in a match as soon as a disallowed char is hit in $name_format
$match = preg_match('/[^sfl[:punct:][:^alnum:]\s]/', $name_format);
if ($match !== false && $match === 0) {
return true;
}
return false;
}
/**
* Checks to see if there was an invalid Name Format encountered during the upgrade
* @return bool true if there was an invalid name, false if all went well.
*/
public function invalidLocaleNameFormatUpgrade()
{
return file_exists($this->invalidNameFormatUpgradeFilename);
}
/**
* Creates the file that is created when there is an invalid name format during an upgrade
*/
public function createInvalidLocaleNameFormatUpgradeNotice()
{
$fh = fopen($this->invalidNameFormatUpgradeFilename, 'wb');
fclose($fh);
}
/**
* Removes the file that is created when there is an invalid name format during an upgrade
*/
public function removeInvalidLocaleNameFormatUpgradeNotice()
{
if ($this->invalidLocaleNameFormatUpgrade()) {
unlink($this->invalidNameFormatUpgradeFilename);
}
}
/**
* Creates dropdown items that have localized example names while filtering out invalid formats
*
* @param array un-prettied dropdown list
* @return array array of dropdown options
*/
public function getUsableLocaleNameOptions($options)
{
global $app_strings;
$examples = array(
's' => $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION'],
'f' => $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST'],
'l' => $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST']
);
$newOpts = array();
foreach ($options as $key => $val) {
if ($this->isAllowedNameFormat($key) && $this->isAllowedNameFormat($val)) {
$newVal = '';
$pieces = str_split($val);
foreach ($pieces as $piece) {
if (isset($examples[$piece])) {
$newVal .= $examples[$piece];
} else {
$newVal .= $piece;
}
}
$newOpts[$key] = $newVal;
}
}
return $newOpts;
}
//// END NAME DISPLAY FORMATTING CODE
///////////////////////////////////////////////////////////////////////////
/**
* Attempts to detect the charset used in the string
*
* @param $str string
* @param $strict bool default false (use strict encoding?)
* @return string
*/
public function detectCharset($str, $strict = false)
{
if (function_exists('mb_convert_encoding')) {
return mb_detect_encoding($str, 'ASCII,JIS,UTF-8,EUC-JP,SJIS,ISO-8859-1', $strict);
}
return false;
}
}