This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); |
||
3 | /********************************************************************************* |
||
4 | * SugarCRM Community Edition is a customer relationship management program developed by |
||
5 | * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
||
6 | |||
7 | * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd. |
||
8 | * Copyright (C) 2011 - 2014 Salesagility Ltd. |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or modify it under |
||
11 | * the terms of the GNU Affero General Public License version 3 as published by the |
||
12 | * Free Software Foundation with the addition of the following permission added |
||
13 | * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
||
14 | * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
||
15 | * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
||
16 | * |
||
17 | * This program is distributed in the hope that it will be useful, but WITHOUT |
||
18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||
19 | * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
||
20 | * details. |
||
21 | * |
||
22 | * You should have received a copy of the GNU Affero General Public License along with |
||
23 | * this program; if not, see http://www.gnu.org/licenses or write to the Free |
||
24 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
||
25 | * 02110-1301 USA. |
||
26 | * |
||
27 | * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
||
28 | * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
||
29 | * |
||
30 | * The interactive user interfaces in modified source and object code versions |
||
31 | * of this program must display Appropriate Legal Notices, as required under |
||
32 | * Section 5 of the GNU Affero General Public License version 3. |
||
33 | * |
||
34 | * In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
||
35 | * these Appropriate Legal Notices must retain the display of the "Powered by |
||
36 | * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
||
37 | * reasonably feasible for technical reasons, the Appropriate Legal Notices must |
||
38 | * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
||
39 | ********************************************************************************/ |
||
40 | |||
41 | /** |
||
42 | * Localization manager |
||
43 | * @api |
||
44 | */ |
||
45 | class Localization { |
||
46 | var $availableCharsets = array( |
||
47 | 'BIG-5', //Taiwan and Hong Kong |
||
48 | /*'CP866' // ms-dos Cyrillic */ |
||
49 | /*'CP949' //Microsoft Korean */ |
||
50 | 'CP1251', //MS Cyrillic |
||
51 | 'CP1252', //MS Western European & US |
||
52 | 'EUC-CN', //Simplified Chinese GB2312 |
||
53 | 'EUC-JP', //Unix Japanese |
||
54 | 'EUC-KR', //Korean |
||
55 | 'EUC-TW', //Taiwanese |
||
56 | 'ISO-2022-JP', //Japanese |
||
57 | 'ISO-2022-KR', //Korean |
||
58 | 'ISO-8859-1', //Western European and US |
||
59 | 'ISO-8859-2', //Central and Eastern European |
||
60 | 'ISO-8859-3', //Latin 3 |
||
61 | 'ISO-8859-4', //Latin 4 |
||
62 | 'ISO-8859-5', //Cyrillic |
||
63 | 'ISO-8859-6', //Arabic |
||
64 | 'ISO-8859-7', //Greek |
||
65 | 'ISO-8859-8', //Hebrew |
||
66 | 'ISO-8859-9', //Latin 5 |
||
67 | 'ISO-8859-10', //Latin 6 |
||
68 | 'ISO-8859-13', //Latin 7 |
||
69 | 'ISO-8859-14', //Latin 8 |
||
70 | 'ISO-8859-15', //Latin 9 |
||
71 | 'KOI8-R', //Cyrillic Russian |
||
72 | 'KOI8-U', //Cyrillic Ukranian |
||
73 | 'SJIS', //MS Japanese |
||
74 | 'UTF-8', //UTF-8 |
||
75 | ); |
||
76 | var $localeNameFormat; |
||
77 | var $localeNameFormatDefault; |
||
78 | var $default_export_charset = 'UTF-8'; |
||
79 | var $default_email_charset = 'UTF-8'; |
||
80 | var $currencies = array(); // array loaded with current currencies |
||
81 | var $invalidNameFormatUpgradeFilename = 'upgradeInvalidLocaleNameFormat.php'; |
||
82 | /* Charset mappings for iconv */ |
||
83 | var $iconvCharsetMap = array( |
||
84 | 'KS_C_5601-1987' => 'CP949', |
||
85 | 'ISO-8859-8-I' => 'ISO-8859-8' |
||
86 | ); |
||
87 | |||
88 | /** |
||
89 | * sole constructor |
||
90 | */ |
||
91 | public function __construct() { |
||
92 | global $sugar_config; |
||
93 | $this->localeNameFormatDefault = empty($sugar_config['locale_name_format_default']) ? 's f l' : $sugar_config['default_name_format']; |
||
94 | $this->loadCurrencies(); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead |
||
99 | */ |
||
100 | public function Localization(){ |
||
101 | $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; |
||
102 | if(isset($GLOBALS['log'])) { |
||
103 | $GLOBALS['log']->deprecated($deprecatedMessage); |
||
104 | } |
||
105 | else { |
||
106 | trigger_error($deprecatedMessage, E_USER_DEPRECATED); |
||
107 | } |
||
108 | self::__construct(); |
||
109 | } |
||
110 | |||
111 | |||
112 | /** |
||
113 | * returns an array of Sugar Config defaults that are determined by locale settings |
||
114 | * @return array |
||
115 | */ |
||
116 | 81 | function getLocaleConfigDefaults() { |
|
117 | $coreDefaults = array( |
||
118 | 81 | 'currency' => '', |
|
119 | 81 | 'datef' => 'm/d/Y', |
|
120 | 81 | 'timef' => 'H:i', |
|
121 | 81 | 'default_currency_significant_digits' => 2, |
|
122 | 81 | 'default_currency_symbol' => '$', |
|
123 | 81 | 'default_export_charset' => $this->default_export_charset, |
|
124 | 81 | 'default_locale_name_format' => 's f l', |
|
125 | 'name_formats' => array('s f l' => 's f l', 'f l' => 'f l', 's l' => 's l', 'l, s f' => 'l, s f', |
||
126 | 'l, f' => 'l, f', 's l, f' => 's l, f', 'l s f' => 'l s f', 'l f s' => 'l f s'), |
||
127 | 81 | 'default_number_grouping_seperator' => ',', |
|
128 | 81 | 'default_decimal_seperator' => '.', |
|
129 | 81 | 'export_delimiter' => ',', |
|
130 | 81 | 'default_email_charset' => $this->default_email_charset, |
|
131 | ); |
||
132 | |||
133 | 81 | return $coreDefaults; |
|
134 | } |
||
135 | |||
136 | /** |
||
137 | * abstraction of precedence |
||
138 | * @param string prefName Name of preference to retrieve based on overrides |
||
139 | * @param object user User in focus, default null (current_user) |
||
140 | * @return string pref Most significant preference |
||
141 | */ |
||
142 | 81 | function getPrecedentPreference($prefName, $user=null, $sugarConfigPrefName = '') { |
|
143 | 81 | global $current_user; |
|
144 | 81 | global $sugar_config; |
|
145 | |||
146 | 81 | $userPref = ''; |
|
147 | 81 | $coreDefaults = $this->getLocaleConfigDefaults(); |
|
148 | 81 | $pref = isset($coreDefaults[$prefName]) ? $coreDefaults[$prefName] : ''; // defaults, even before config.php |
|
149 | |||
150 | 81 | if($user != null) { |
|
151 | 64 | $userPref = $user->getPreference($prefName); |
|
152 | 17 | } elseif(!empty($current_user)) { |
|
153 | 17 | $userPref = $current_user->getPreference($prefName); |
|
154 | } |
||
155 | // Bug 39171 - If we are asking for default_email_charset, check in emailSettings['defaultOutboundCharset'] as well |
||
156 | 81 | if ( $prefName == 'default_email_charset' ) { |
|
157 | 7 | if($user != null) { |
|
158 | $emailSettings = $user->getPreference('emailSettings', 'Emails'); |
||
159 | 7 | } elseif(!empty($current_user)) { |
|
160 | 7 | $emailSettings = $current_user->getPreference('emailSettings', 'Emails'); |
|
161 | } |
||
162 | 7 | if ( isset($emailSettings['defaultOutboundCharset']) ) { |
|
163 | $userPref = $emailSettings['defaultOutboundCharset']; |
||
164 | } |
||
165 | } |
||
166 | |||
167 | // set fallback defaults defined in this class |
||
168 | 81 | if(isset($this->$prefName)) { |
|
169 | 9 | $pref = $this->$prefName; |
|
170 | } |
||
171 | //rrs: 33086 - give the ability to pass in the preference name as stored in $sugar_config. |
||
172 | 81 | if(!empty($sugarConfigPrefName)){ |
|
173 | $prefName = $sugarConfigPrefName; |
||
174 | } |
||
175 | // cn: 9549 empty() call on a value of 0 (0 significant digits) resulted in a false-positive. changing to "isset()" |
||
176 | 81 | $pref = (!isset($sugar_config[$prefName]) || (empty($sugar_config[$prefName]) && $sugar_config[$prefName] !== '0')) ? $pref : $sugar_config[$prefName]; |
|
177 | 81 | $pref = (empty($userPref) && $userPref !== '0') ? $pref : $userPref; |
|
178 | 81 | return $pref; |
|
179 | } |
||
180 | |||
181 | /////////////////////////////////////////////////////////////////////////// |
||
182 | //// CURRENCY HANDLING |
||
183 | /** |
||
184 | * wrapper for whatever currency system we implement |
||
185 | */ |
||
186 | function loadCurrencies() { |
||
187 | // doing it dirty here |
||
188 | global $db; |
||
189 | global $sugar_config; |
||
190 | |||
191 | if(empty($db)) { |
||
192 | return array(); |
||
193 | } |
||
194 | |||
195 | $load = sugar_cache_retrieve('currency_list'); |
||
196 | if ( !is_array($load) ) { |
||
197 | // load default from config.php |
||
198 | $this->currencies['-99'] = array( |
||
199 | 'name' => $sugar_config['default_currency_name'], |
||
200 | 'symbol' => $sugar_config['default_currency_symbol'], |
||
201 | 'conversion_rate' => 1 |
||
202 | ); |
||
203 | |||
204 | $q = "SELECT id, name, symbol, conversion_rate FROM currencies WHERE status = 'Active' and deleted = 0"; |
||
205 | $r = $db->query($q); |
||
206 | |||
207 | while($a = $db->fetchByAssoc($r)) { |
||
208 | $load = array(); |
||
209 | $load['name'] = $a['name']; |
||
210 | $load['symbol'] = $a['symbol']; |
||
211 | $load['conversion_rate'] = $a['conversion_rate']; |
||
212 | |||
213 | $this->currencies[$a['id']] = $load; |
||
214 | } |
||
215 | sugar_cache_put('currency_list',$this->currencies); |
||
216 | } else { |
||
217 | $this->currencies = $load; |
||
218 | } |
||
219 | |||
220 | |||
221 | } |
||
222 | |||
223 | /** |
||
224 | * getter for currencies array |
||
225 | * @return array $this->currencies returns array( id => array(name => X, etc |
||
226 | */ |
||
227 | function getCurrencies() { |
||
228 | return $this->currencies; |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * retrieves default OOTB currencies for sugar_config and installer. |
||
233 | * @return array ret Array of default currencies keyed by ISO4217 code |
||
234 | */ |
||
235 | function getDefaultCurrencies() { |
||
236 | $ret = array( |
||
237 | 'AUD' => array( 'name' => 'Australian Dollars', |
||
238 | 'iso4217' => 'AUD', |
||
239 | 'symbol' => '$'), |
||
240 | 'BRL' => array( 'name' => 'Brazilian Reais', |
||
241 | 'iso4217' => 'BRL', |
||
242 | 'symbol' => 'R$'), |
||
243 | 'GBP' => array( 'name' => 'British Pounds', |
||
244 | 'iso4217' => 'GBP', |
||
245 | 'symbol' => '£'), |
||
246 | 'CAD' => array( 'name' => 'Canadian Dollars', |
||
247 | 'iso4217' => 'CAD', |
||
248 | 'symbol' => '$'), |
||
249 | 'CNY' => array( 'name' => 'Chinese Yuan', |
||
250 | 'iso4217' => 'CNY', |
||
251 | 'symbol' => 'ï¿¥'), |
||
252 | 'EUR' => array( 'name' => 'Euro', |
||
253 | 'iso4217' => 'EUR', |
||
254 | 'symbol' => '€'), |
||
255 | 'HKD' => array( 'name' => 'Hong Kong Dollars', |
||
256 | 'iso4217' => 'HKD', |
||
257 | 'symbol' => '$'), |
||
258 | 'INR' => array( 'name' => 'Indian Rupees', |
||
259 | 'iso4217' => 'INR', |
||
260 | 'symbol' => '₨'), |
||
261 | 'KRW' => array( 'name' => 'Korean Won', |
||
262 | 'iso4217' => 'KRW', |
||
263 | 'symbol' => 'â‚©'), |
||
264 | 'YEN' => array( 'name' => 'Japanese Yen', |
||
265 | 'iso4217' => 'JPY', |
||
266 | 'symbol' => 'Â¥'), |
||
267 | 'MXM' => array( 'name' => 'Mexican Pesos', |
||
268 | 'iso4217' => 'MXM', |
||
269 | 'symbol' => '$'), |
||
270 | 'SGD' => array( 'name' => 'Singaporean Dollars', |
||
271 | 'iso4217' => 'SGD', |
||
272 | 'symbol' => '$'), |
||
273 | 'CHF' => array( 'name' => 'Swiss Franc', |
||
274 | 'iso4217' => 'CHF', |
||
275 | 'symbol' => 'SFr.'), |
||
276 | 'THB' => array( 'name' => 'Thai Baht', |
||
277 | 'iso4217' => 'THB', |
||
278 | 'symbol' => '฿'), |
||
279 | 'USD' => array( 'name' => 'US Dollars', |
||
280 | 'iso4217' => 'USD', |
||
281 | 'symbol' => '$'), |
||
282 | ); |
||
283 | |||
284 | return $ret; |
||
285 | } |
||
286 | //// END CURRENCY HANDLING |
||
287 | /////////////////////////////////////////////////////////////////////////// |
||
288 | |||
289 | |||
290 | /////////////////////////////////////////////////////////////////////////// |
||
291 | //// CHARSET TRANSLATION |
||
292 | /** |
||
293 | * returns a mod|app_strings array in the target charset |
||
294 | * @param array strings $mod_string, et.al. |
||
295 | * @param string charset Target charset |
||
296 | * @return array Translated string pack |
||
297 | */ |
||
298 | function translateStringPack($strings, $charset) { |
||
299 | // handle recursive |
||
300 | foreach($strings as $k => $v) { |
||
301 | if(is_array($v)) { |
||
302 | $strings[$k] = $this->translateStringPack($v, $charset); |
||
303 | } else { |
||
304 | $strings[$k] = $this->translateCharset($v, 'UTF-8', $charset); |
||
305 | } |
||
306 | } |
||
307 | ksort($strings); |
||
308 | return $strings; |
||
309 | } |
||
310 | |||
311 | /** |
||
312 | * translates the passed variable for email sending (export) |
||
313 | * @param mixed the var (array or string) to translate |
||
314 | * @return mixed the translated variable |
||
315 | */ |
||
316 | function translateForEmail($var) { |
||
317 | if(is_array($var)) { |
||
318 | foreach($var as $k => $v) { |
||
319 | $var[$k] = $this->translateForEmail($v); |
||
320 | } |
||
321 | return $var; |
||
322 | } elseif(!empty($var)) { |
||
323 | return $this->translateCharset($var, 'UTF-8', $this->getOutboundEmailCharset()); |
||
324 | } |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * prepares a bean for export by translating any text fields into the export |
||
329 | * character set |
||
330 | * @param bean object A SugarBean |
||
331 | * @return bean object The bean with translated strings |
||
332 | */ |
||
333 | function prepBeanForExport($bean) |
||
334 | { |
||
335 | foreach($bean->field_defs as $k => $field) |
||
336 | { |
||
337 | if (is_string($bean->$k)) |
||
0 ignored issues
–
show
|
|||
338 | { |
||
339 | // $bean->$k = $this->translateCharset($bean->$k, 'UTF-8', $this->getExportCharset()); |
||
340 | } |
||
341 | else |
||
342 | { |
||
343 | $bean->$k = ''; |
||
344 | } |
||
345 | } |
||
346 | |||
347 | return $bean; |
||
348 | } |
||
349 | |||
350 | /** |
||
351 | * translates a character set from one encoding to another encoding |
||
352 | * @param string string the string to be translated |
||
353 | * @param string fromCharset the charset the string is currently in |
||
354 | * @param string toCharset the charset to translate into (defaults to UTF-8) |
||
355 | * @param bool forceIconv force using the iconv library instead of mb_string |
||
356 | * @return string the translated string |
||
357 | */ |
||
358 | 9 | function translateCharset($string, $fromCharset, $toCharset='UTF-8', $forceIconv = false) |
|
359 | { |
||
360 | 9 | $GLOBALS['log']->debug("Localization: translating [{$string}] from {$fromCharset} into {$toCharset}"); |
|
361 | |||
362 | // Bug #35413 Function has to use iconv if $fromCharset is not in mb_list_encodings |
||
363 | 9 | $isMb = function_exists('mb_convert_encoding') && !$forceIconv; |
|
364 | 9 | $isIconv = function_exists('iconv'); |
|
365 | 9 | if ($isMb == true) |
|
0 ignored issues
–
show
|
|||
366 | { |
||
367 | 9 | $fromCharset = strtoupper($fromCharset); |
|
368 | 9 | $listEncodings = mb_list_encodings(); |
|
369 | 9 | $isFound = false; |
|
370 | 9 | foreach ($listEncodings as $encoding) |
|
371 | { |
||
372 | 9 | if (strtoupper($encoding) == $fromCharset) |
|
373 | { |
||
374 | 8 | $isFound = true; |
|
375 | 9 | break; |
|
376 | } |
||
377 | } |
||
378 | 9 | $isMb = $isFound; |
|
379 | } |
||
380 | |||
381 | 9 | if($isMb) |
|
382 | { |
||
383 | 8 | return mb_convert_encoding($string, $toCharset, $fromCharset); |
|
384 | } |
||
385 | 1 | elseif($isIconv) |
|
386 | { |
||
387 | 1 | $newFromCharset = $fromCharset; |
|
388 | 1 | if (isset($this->iconvCharsetMap[$fromCharset])) { |
|
389 | $newFromCharset = $this->iconvCharsetMap[$fromCharset]; |
||
390 | $GLOBALS['log']->debug("Localization: iconv using charset {$newFromCharset} instead of {$fromCharset}"); |
||
391 | } |
||
392 | 1 | $newToCharset = $toCharset; |
|
393 | 1 | if (isset($this->iconvCharsetMap[$toCharset])) { |
|
394 | $newToCharset = $this->iconvCharsetMap[$toCharset]; |
||
395 | $GLOBALS['log']->debug("Localization: iconv using charset {$newToCharset} instead of {$toCharset}"); |
||
396 | } |
||
397 | 1 | return iconv($newFromCharset, $newToCharset, $string); |
|
398 | } |
||
399 | else |
||
400 | { |
||
401 | return $string; |
||
402 | } // end else clause |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * translates a character set from one to another, and the into MIME-header friendly format |
||
407 | */ |
||
408 | 3 | function translateCharsetMIME($string, $fromCharset, $toCharset='UTF-8', $encoding="Q") { |
|
409 | 3 | $previousEncoding = mb_internal_encoding(); |
|
410 | 3 | mb_internal_encoding($fromCharset); |
|
411 | 3 | $result = mb_encode_mimeheader($string, $toCharset, $encoding); |
|
412 | 3 | mb_internal_encoding($previousEncoding); |
|
413 | 3 | return $result; |
|
414 | } |
||
415 | |||
416 | function normalizeCharset($charset) { |
||
417 | $charset = strtolower(preg_replace("/[\-\_]*/", "", $charset)); |
||
418 | return $charset; |
||
419 | } |
||
420 | |||
421 | /** |
||
422 | * returns an array of charsets with keys for available translations; appropriate for get_select_options_with_id() |
||
423 | */ |
||
424 | function getCharsetSelect() { |
||
425 | //jc:12293 - the "labels" or "human-readable" representations of the various charsets |
||
426 | //should be translatable |
||
427 | $translated = array(); |
||
428 | foreach($this->availableCharsets as $key) |
||
429 | { |
||
430 | //$translated[$key] = translate($value); |
||
431 | $translated[$key] = translate($key); |
||
432 | } |
||
433 | |||
434 | return $translated; |
||
435 | //end:12293 |
||
436 | } |
||
437 | |||
438 | /** |
||
439 | * returns the charset preferred in descending order: User, Sugar Config, DEFAULT |
||
440 | * @param string charset to override ALL, pass a valid charset here |
||
441 | * @return string charset the chosen character set |
||
442 | */ |
||
443 | 2 | function getExportCharset($charset='', $user=null) { |
|
444 | 2 | $charset = $this->getPrecedentPreference('default_export_charset', $user); |
|
445 | 2 | return $charset; |
|
446 | } |
||
447 | |||
448 | /** |
||
449 | * returns the charset preferred in descending order: User, Sugar Config, DEFAULT |
||
450 | * @return string charset the chosen character set |
||
451 | */ |
||
452 | function getOutboundEmailCharset($user=null) { |
||
453 | $charset = $this->getPrecedentPreference('default_email_charset', $user); |
||
454 | return $charset; |
||
455 | } |
||
456 | //// END CHARSET TRANSLATION |
||
457 | /////////////////////////////////////////////////////////////////////////// |
||
458 | |||
459 | /////////////////////////////////////////////////////////////////////////// |
||
460 | //// NUMBER DISPLAY FORMATTING CODE |
||
461 | function getDecimalSeparator($user=null) { |
||
462 | // Bug50887 this is purposefully misspelled as ..._seperator to match the way it's defined throughout the app. |
||
463 | $dec = $this->getPrecedentPreference('default_decimal_seperator', $user); |
||
464 | return $dec; |
||
465 | } |
||
466 | |||
467 | function getNumberGroupingSeparator($user=null) { |
||
468 | $sep = $this->getPrecedentPreference('default_number_grouping_seperator', $user); |
||
469 | return $sep; |
||
470 | } |
||
471 | |||
472 | 2 | function getPrecision($user=null) { |
|
473 | 2 | $precision = $this->getPrecedentPreference('default_currency_significant_digits', $user); |
|
474 | 2 | return $precision; |
|
475 | } |
||
476 | |||
477 | function getCurrencySymbol($user=null) { |
||
478 | $dec = $this->getPrecedentPreference('default_currency_symbol', $user); |
||
479 | return $dec; |
||
480 | } |
||
481 | |||
482 | /** |
||
483 | * returns a number formatted by user preference or system default |
||
484 | * @param string number Number to be formatted and returned |
||
485 | * @param string currencySymbol Currency symbol if override is necessary |
||
486 | * @param bool is_currency Flag to also return the currency symbol |
||
487 | * @return string Formatted number |
||
488 | */ |
||
489 | function getLocaleFormattedNumber($number, $currencySymbol='', $is_currency=true, $user=null) { |
||
490 | $fnum = $number; |
||
491 | $majorDigits = ''; |
||
492 | $minorDigits = ''; |
||
493 | $dec = $this->getDecimalSeparator($user); |
||
494 | $thou = $this->getNumberGroupingSeparator($user); |
||
495 | $precision = $this->getPrecision($user); |
||
496 | $symbol = empty($currencySymbol) ? $this->getCurrencySymbol($user) : $currencySymbol; |
||
497 | |||
498 | $exNum = explode($dec, $number); |
||
499 | // handle grouping |
||
500 | if(is_array($exNum) && count($exNum) > 0) { |
||
501 | if(strlen($exNum[0]) > 3) { |
||
502 | $offset = strlen($exNum[0]) % 3; |
||
503 | if($offset > 0) { |
||
504 | for($i=0; $i<$offset; $i++) { |
||
505 | $majorDigits .= $exNum[0]{$i}; |
||
506 | } |
||
507 | } |
||
508 | |||
509 | $tic = 0; |
||
510 | for($i=$offset; $i<strlen($exNum[0]); $i++) { |
||
511 | if($tic % 3 == 0 && $i != 0) { |
||
512 | $majorDigits .= $thou; // add separator |
||
513 | } |
||
514 | |||
515 | $majorDigits .= $exNum[0]{$i}; |
||
516 | $tic++; |
||
517 | } |
||
518 | } else { |
||
519 | $majorDigits = $exNum[0]; // no formatting needed |
||
520 | } |
||
521 | $fnum = $majorDigits; |
||
522 | } |
||
523 | |||
524 | // handle decimals |
||
525 | if($precision > 0) { // we toss the minor digits otherwise |
||
526 | if(is_array($exNum) && isset($exNum[1])) { |
||
0 ignored issues
–
show
This
if statement is empty and can be removed.
This check looks for the bodies of These if (rand(1, 6) > 3) {
//print "Check failed";
} else {
print "Check succeeded";
}
could be turned into if (rand(1, 6) <= 3) {
print "Check succeeded";
}
This is much more concise to read. ![]() |
|||
527 | |||
528 | } |
||
529 | } |
||
530 | |||
531 | |||
532 | if($is_currency) { |
||
533 | $fnum = $symbol.$fnum; |
||
534 | } |
||
535 | return $fnum; |
||
536 | } |
||
537 | |||
538 | /** |
||
539 | * returns Javascript to format numbers and currency for ***DISPLAY*** |
||
540 | */ |
||
541 | function getNumberJs() { |
||
542 | $out = <<<eoq |
||
543 | |||
544 | var exampleDigits = '123456789.000000'; |
||
545 | |||
546 | // round parameter can be negative for decimal, precision has to be postive |
||
547 | function formatNumber(n, sep, dec, precision) { |
||
548 | var majorDigits; |
||
549 | var minorDigits; |
||
550 | var formattedMajor = ''; |
||
551 | var formattedMinor = ''; |
||
552 | |||
553 | var nArray = n.split('.'); |
||
554 | majorDigits = nArray[0]; |
||
555 | if(nArray.length < 2) { |
||
556 | minorDigits = 0; |
||
557 | } else { |
||
558 | minorDigits = nArray[1]; |
||
559 | } |
||
560 | |||
561 | // handle grouping |
||
562 | if(sep.length > 0) { |
||
563 | var strlength = majorDigits.length; |
||
564 | |||
565 | if(strlength > 3) { |
||
566 | var offset = strlength % 3; // find how many to lead off by |
||
567 | |||
568 | for(j=0; j<offset; j++) { |
||
569 | formattedMajor += majorDigits[j]; |
||
570 | } |
||
571 | |||
572 | tic=0; |
||
573 | for(i=offset; i<strlength; i++) { |
||
574 | if(tic % 3 == 0 && i != 0) |
||
575 | formattedMajor += sep; |
||
576 | |||
577 | formattedMajor += majorDigits.substr(i,1); |
||
578 | tic++; |
||
579 | } |
||
580 | } |
||
581 | } else { |
||
582 | formattedMajor = majorDigits; // no grouping marker |
||
583 | } |
||
584 | |||
585 | // handle decimal precision |
||
586 | if(precision > 0) { |
||
587 | for(i=0; i<precision; i++) { |
||
588 | if(minorDigits[i] != undefined) |
||
589 | formattedMinor += minorDigits[i]; |
||
590 | else |
||
591 | formattedMinor += '0'; |
||
592 | } |
||
593 | } else { |
||
594 | // we're just returning the major digits, no decimal marker |
||
595 | dec = ''; // just in case |
||
596 | } |
||
597 | |||
598 | return formattedMajor + dec + formattedMinor; |
||
599 | } |
||
600 | |||
601 | function setSigDigits() { |
||
602 | var sym = document.getElementById('symbol').value; |
||
603 | var thou = document.getElementById('default_number_grouping_seperator').value; |
||
604 | var dec = document.getElementById('default_decimal_seperator').value; |
||
605 | var precision = document.getElementById('sigDigits').value; |
||
606 | //umber(n, num_grp_sep, dec_sep, round, precision) |
||
607 | var newNumber = sym + formatNumber(exampleDigits, thou, dec, precision, precision); |
||
608 | document.getElementById('sigDigitsExample').value = newNumber; |
||
609 | } |
||
610 | eoq; |
||
611 | return $out; |
||
612 | } |
||
613 | |||
614 | //// END NUMBER DISPLAY FORMATTING CODE |
||
615 | /////////////////////////////////////////////////////////////////////////// |
||
616 | |||
617 | /////////////////////////////////////////////////////////////////////////// |
||
618 | //// NAME DISPLAY FORMATTING CODE |
||
619 | /** |
||
620 | * get's the Name format macro string, preferring $current_user |
||
621 | * @return string format Name Format macro for locale |
||
622 | */ |
||
623 | 68 | function getLocaleFormatMacro($user=null) { |
|
624 | 68 | $returnFormat = $this->getPrecedentPreference('default_locale_name_format', $user); |
|
625 | 68 | return $returnFormat; |
|
626 | } |
||
627 | |||
628 | /** |
||
629 | * returns formatted name according to $current_user's locale settings |
||
630 | * |
||
631 | * @param string firstName |
||
632 | * @param string lastName |
||
633 | * @param string salutation |
||
634 | * @param string title |
||
635 | * @param string format If a particular format is desired, then pass this optional parameter as a simple string. |
||
636 | * sfl is "Salutation FirstName LastName", "l, f s" is "LastName[comma][space]FirstName[space]Salutation" |
||
637 | * @param object user object |
||
638 | * @param bool returnEmptyStringIfEmpty true if we should return back an empty string rather than a single space |
||
639 | * when the formatted name would be blank |
||
640 | * @return string formattedName |
||
641 | */ |
||
642 | 93 | function getLocaleFormattedName($firstName, $lastName, $salutationKey='', $title='', $format="", $user=null, $returnEmptyStringIfEmpty = false) { |
|
643 | 93 | global $current_user; |
|
644 | 93 | global $app_list_strings; |
|
645 | |||
646 | 93 | if ( $user == null ) { |
|
647 | 93 | $user = $current_user; |
|
648 | } |
||
649 | |||
650 | 93 | $salutation = $salutationKey; |
|
651 | 93 | if(!empty($salutationKey) && !empty($app_list_strings['salutation_dom'][$salutationKey])) { |
|
652 | $salutation = (!empty($app_list_strings['salutation_dom'][$salutationKey]) ? $app_list_strings['salutation_dom'][$salutationKey] : $salutationKey); |
||
653 | } |
||
654 | |||
655 | //check to see if passed in variables are set, if so, then populate array with value, |
||
656 | //if not, then populate array with blank '' |
||
657 | 93 | $names = array(); |
|
658 | 93 | $names['f'] = (empty($firstName) && $firstName != 0) ? '' : $firstName; |
|
659 | 93 | $names['l'] = (empty($lastName) && $lastName != 0) ? '' : $lastName; |
|
660 | 93 | $names['s'] = (empty($salutation) && $salutation != 0) ? '' : $salutation; |
|
661 | 93 | $names['t'] = (empty($title) && $title != 0) ? '' : $title; |
|
662 | |||
663 | //Bug: 39936 - if all of the inputs are empty, then don't try to format the name. |
||
664 | 93 | $allEmpty = true; |
|
665 | 93 | foreach($names as $key => $val){ |
|
666 | 93 | if(!empty($val)){ |
|
667 | 63 | $allEmpty = false; |
|
668 | 93 | break; |
|
669 | } |
||
670 | } |
||
671 | 93 | if($allEmpty){ |
|
672 | 39 | return $returnEmptyStringIfEmpty ? '' : ' '; |
|
673 | } |
||
674 | //end Bug: 39936 |
||
675 | |||
676 | 63 | if(empty($format)) { |
|
677 | 63 | $this->localeNameFormat = $this->getLocaleFormatMacro($user); |
|
678 | } else { |
||
679 | $this->localeNameFormat = $format; |
||
680 | } |
||
681 | |||
682 | // parse localeNameFormat |
||
683 | 63 | $formattedName = ''; |
|
684 | 63 | for($i=0; $i<strlen($this->localeNameFormat); $i++) { |
|
685 | 63 | $formattedName .= array_key_exists($this->localeNameFormat{$i}, $names) ? $names[$this->localeNameFormat{$i}] : $this->localeNameFormat{$i}; |
|
686 | } |
||
687 | |||
688 | 63 | $formattedName = trim($formattedName); |
|
689 | 63 | if (strlen($formattedName)==0) { |
|
690 | return $returnEmptyStringIfEmpty ? '' : ' '; |
||
691 | } |
||
692 | |||
693 | 63 | if(strpos($formattedName,',',strlen($formattedName)-1)) { // remove trailing commas |
|
694 | $formattedName = substr($formattedName, 0, strlen($formattedName)-1); |
||
695 | } |
||
696 | 63 | return trim($formattedName); |
|
697 | } |
||
698 | |||
699 | /** |
||
700 | * outputs some simple Javascript to show a preview of Name format in "My Account" and "Admin->Localization" |
||
701 | * @param string first First Name, use app_strings default if not specified |
||
702 | * @param string last Last Name, use app_strings default if not specified |
||
703 | * @param string salutation Saluation, use app_strings default if not specified |
||
704 | * @return string some Javascript |
||
705 | */ |
||
706 | function getNameJs($first='', $last='', $salutation='', $title='') { |
||
707 | global $app_strings; |
||
708 | |||
709 | $salutation = !empty($salutation) ? $salutation : $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION']; |
||
710 | $first = !empty($first) ? $first : $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST']; |
||
711 | $last = !empty($last) ? $last : $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST']; |
||
712 | $title = !empty($title) ? $title : $app_strings['LBL_LOCALE_NAME_EXAMPLE_TITLE']; |
||
713 | |||
714 | $ret = " |
||
715 | function setPreview() { |
||
716 | format = document.getElementById('default_locale_name_format').value; |
||
717 | field = document.getElementById('nameTarget'); |
||
718 | |||
719 | stuff = new Object(); |
||
720 | |||
721 | stuff['s'] = '{$salutation}'; |
||
722 | stuff['f'] = '{$first}'; |
||
723 | stuff['l'] = '{$last}'; |
||
724 | stuff['t'] = '{$title}'; |
||
725 | |||
726 | var name = ''; |
||
727 | for(i=0; i<format.length; i++) { |
||
728 | if(stuff[format.substr(i,1)] != undefined) { |
||
729 | name += stuff[format.substr(i,1)]; |
||
730 | } else { |
||
731 | name += format.substr(i,1); |
||
732 | } |
||
733 | } |
||
734 | |||
735 | //alert(name); |
||
736 | field.value = name; |
||
737 | } |
||
738 | |||
739 | "; |
||
740 | |||
741 | return $ret; |
||
742 | } |
||
743 | |||
744 | /** |
||
745 | * Checks to see that the characters in $name_format are allowed: s, f, l, space/tab or punctuation |
||
746 | * @param $name_format |
||
747 | * @return bool |
||
748 | */ |
||
749 | public function isAllowedNameFormat($name_format) { |
||
750 | // will result in a match as soon as a disallowed char is hit in $name_format |
||
751 | $match = preg_match('/[^sfl[:punct:][:^alnum:]\s]/', $name_format); |
||
752 | if ($match !== false && $match === 0) { |
||
753 | return true; |
||
754 | } |
||
755 | return false; |
||
756 | } |
||
757 | |||
758 | /** |
||
759 | * Checks to see if there was an invalid Name Format encountered during the upgrade |
||
760 | * @return bool true if there was an invalid name, false if all went well. |
||
761 | */ |
||
762 | public function invalidLocaleNameFormatUpgrade() { |
||
763 | return file_exists($this->invalidNameFormatUpgradeFilename); |
||
764 | } |
||
765 | |||
766 | /** |
||
767 | * Creates the file that is created when there is an invalid name format during an upgrade |
||
768 | */ |
||
769 | public function createInvalidLocaleNameFormatUpgradeNotice() { |
||
770 | $fh = fopen($this->invalidNameFormatUpgradeFilename,'w'); |
||
771 | fclose($fh); |
||
772 | } |
||
773 | |||
774 | /** |
||
775 | * Removes the file that is created when there is an invalid name format during an upgrade |
||
776 | */ |
||
777 | public function removeInvalidLocaleNameFormatUpgradeNotice() { |
||
778 | if ($this->invalidLocaleNameFormatUpgrade()) { |
||
779 | unlink($this->invalidNameFormatUpgradeFilename); |
||
780 | } |
||
781 | } |
||
782 | |||
783 | |||
784 | /** |
||
785 | * Creates dropdown items that have localized example names while filtering out invalid formats |
||
786 | * |
||
787 | * @param array un-prettied dropdown list |
||
788 | * @return array array of dropdown options |
||
789 | */ |
||
790 | public function getUsableLocaleNameOptions($options) { |
||
791 | global $app_strings; |
||
792 | |||
793 | $examples = array('s' => $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION'], |
||
794 | 'f' => $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST'], |
||
795 | 'l' => $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST']); |
||
796 | $newOpts = array(); |
||
797 | foreach ($options as $key => $val) { |
||
798 | if ($this->isAllowedNameFormat($key) && $this->isAllowedNameFormat($val)) { |
||
799 | $newVal = ''; |
||
800 | $pieces = str_split($val); |
||
801 | foreach ($pieces as $piece) { |
||
802 | if (isset($examples[$piece])) { |
||
803 | $newVal .= $examples[$piece]; |
||
804 | } else { |
||
805 | $newVal .= $piece; |
||
806 | } |
||
807 | } |
||
808 | $newOpts[$key] = $newVal; |
||
809 | } |
||
810 | } |
||
811 | return $newOpts; |
||
812 | } |
||
813 | //// END NAME DISPLAY FORMATTING CODE |
||
814 | /////////////////////////////////////////////////////////////////////////// |
||
815 | |||
816 | /** |
||
817 | * Attempts to detect the charset used in the string |
||
818 | * |
||
819 | * @param $str string |
||
820 | * @param $strict bool default false (use strict encoding?) |
||
821 | * @return string |
||
822 | */ |
||
823 | 2 | public function detectCharset($str, $strict=false) |
|
824 | { |
||
825 | 2 | if ( function_exists('mb_convert_encoding') ) |
|
826 | 2 | return mb_detect_encoding($str,'ASCII,JIS,UTF-8,EUC-JP,SJIS,ISO-8859-1',$strict); |
|
827 | |||
828 | return false; |
||
829 | } |
||
830 | } // end class def |
||
831 | |||
832 | ?> |
This check looks for the bodies of
if
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
if
bodies can be removed. If you have an empty if but statements in theelse
branch, consider inverting the condition.could be turned into
This is much more concise to read.