2 /*********************************************************************************
3 * SugarCRM Community Edition is a customer relationship management program developed by
4 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Affero General Public License version 3 as published by the
8 * Free Software Foundation with the addition of the following permission added
9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18 * You should have received a copy of the GNU Affero General Public License along with
19 * this program; if not, see http://www.gnu.org/licenses or write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26 * The interactive user interfaces in modified source and object code versions
27 * of this program must display Appropriate Legal Notices, as required under
28 * Section 5 of the GNU Affero General Public License version 3.
30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31 * these Appropriate Legal Notices must retain the display of the "Powered by
32 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33 * technical reasons, the Appropriate Legal Notices must display the words
34 * "Powered by SugarCRM".
35 ********************************************************************************/
37 /*********************************************************************************
39 * Description: Includes generic helper functions used throughout the application.
40 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
41 * All Rights Reserved.
42 * Contributor(s): ______________________________________..
43 ********************************************************************************/
44 require_once('include/SugarObjects/SugarConfig.php');
45 require_once('include/utils/security_utils.php');
49 function make_sugar_config(&$sugar_config)
51 /* used to convert non-array config.php file to array format */
52 global $admin_export_only;
54 global $calculate_response_time;
55 global $create_default_user;
58 global $dbconfigoption;
59 global $default_action;
60 global $default_charset;
61 global $default_currency_name;
62 global $default_currency_symbol;
63 global $default_currency_iso4217;
64 global $defaultDateFormat;
65 global $default_language;
66 global $default_module;
67 global $default_password;
68 global $default_permission_mode;
69 global $default_theme;
70 global $defaultTimeFormat;
71 global $default_user_is_admin;
72 global $default_user_name;
73 global $disable_export;
74 global $disable_persistent_connections;
75 global $display_email_template_variable_chooser;
76 global $display_inbound_email_buttons;
77 global $history_max_viewed;
81 global $list_max_entries_per_page;
82 global $lock_default_user_name;
83 global $log_memory_usage;
84 global $requireAccounts;
85 global $RSS_CACHE_TIME;
89 global $sugar_version;
92 global $translation_string_prefix;
94 global $upload_badext;
96 global $upload_maxsize;
97 global $import_max_execution_time;
98 global $list_max_entries_per_subpanel;
99 global $passwordsetting;
101 // assumes the following variables must be set:
102 // $dbconfig, $dbconfigoption, $cache_dir, $import_dir, $session_dir, $site_URL, $tmp_dir, $upload_dir
104 $sugar_config = array (
105 'admin_export_only' => empty($admin_export_only) ? false : $admin_export_only,
106 'export_delimiter' => empty($export_delimiter) ? ',' : $export_delimiter,
107 'cache_dir' => empty($cache_dir) ? 'cache/' : $cache_dir,
108 'calculate_response_time' => empty($calculate_response_time) ? true : $calculate_response_time,
109 'create_default_user' => empty($create_default_user) ? false : $create_default_user,
110 'chartEngine' => 'Jit',
111 'date_formats' => empty($dateFormats) ? array(
112 'Y-m-d'=>'2010-12-23',
113 'd-m-Y' => '23-12-2010',
114 'm-d-Y'=>'12-23-2010',
115 'Y/m/d'=>'2010/12/23',
116 'd/m/Y' => '23/12/2010',
117 'm/d/Y'=>'12/23/2010',
118 'Y.m.d' => '2010.12.23',
119 'd.m.Y' => '23.12.2010',
120 'm.d.Y' => '12.23.2010'
122 'dbconfig' => $dbconfig, // this must be set!!
123 'dbconfigoption' => $dbconfigoption, // this must be set!!
124 'default_action' => empty($default_action) ? 'index' : $default_action,
125 'default_charset' => empty($default_charset) ? 'UTF-8' : $default_charset,
126 'default_currency_name' => empty($default_currency_name) ? 'US Dollar' : $default_currency_name,
127 'default_currency_symbol' => empty($default_currency_symbol) ? '$' : $default_currency_symbol,
128 'default_currency_iso4217' => empty($default_currency_iso4217) ? '$' : $default_currency_iso4217,
129 'default_date_format' => empty($defaultDateFormat) ? 'm/d/Y' : $defaultDateFormat,
130 'default_export_charset' => 'UTF-8',
131 'default_language' => empty($default_language) ? 'en_us' : $default_language,
132 'default_module' => empty($default_module) ? 'Home' : $default_module,
133 'default_password' => empty($default_password) ? '' : $default_password,
134 'default_permissions' => array (
140 'default_theme' => empty($default_theme) ? 'Sugar5' : $default_theme,
141 'default_time_format' => empty($defaultTimeFormat) ? 'h:ia' : $defaultTimeFormat,
142 'default_user_is_admin' => empty($default_user_is_admin) ? false : $default_user_is_admin,
143 'default_user_name' => empty($default_user_name) ? '' : $default_user_name,
144 'disable_export' => empty($disable_export) ? false : $disable_export,
145 'disable_persistent_connections' => empty($disable_persistent_connections) ? false : $disable_persistent_connections,
146 'display_email_template_variable_chooser' => empty($display_email_template_variable_chooser) ? false : $display_email_template_variable_chooser,
147 'display_inbound_email_buttons' => empty($display_inbound_email_buttons) ? false : $display_inbound_email_buttons,
148 'history_max_viewed' => empty($history_max_viewed) ? 50 : $history_max_viewed,
149 'host_name' => empty($host_name) ? 'localhost' : $host_name,
150 'import_dir' => $import_dir, // this must be set!!
151 'import_max_records_per_file' => 100,
152 'languages' => empty($languages) ? array('en_us' => 'English (US)') : $languages,
153 'list_max_entries_per_page' => empty($list_max_entries_per_page) ? 20 : $list_max_entries_per_page,
154 'list_max_entries_per_subpanel' => empty($list_max_entries_per_subpanel) ? 10 : $list_max_entries_per_subpanel,
155 'lock_default_user_name' => empty($lock_default_user_name) ? false : $lock_default_user_name,
156 'log_memory_usage' => empty($log_memory_usage) ? false : $log_memory_usage,
157 'portal_view' => 'single_user',
158 'resource_management' => array (
159 'special_query_limit' => 50000,
160 'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'),
161 'default_limit' => 1000,
163 'require_accounts' => empty($requireAccounts) ? true : $requireAccounts,
164 'rss_cache_time' => empty($RSS_CACHE_TIME) ? '10800' : $RSS_CACHE_TIME,
165 'session_dir' => $session_dir, // this must be set!!
166 'site_url' => empty($site_URL) ? $site_url : $site_URL, // this must be set!!
167 'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable
168 'showThemePicker' => true,
169 'sugar_version' => empty($sugar_version) ? 'unknown' : $sugar_version,
170 'time_formats' => empty($timeFormats) ? array (
171 'H:i'=>'23:00', 'h:ia'=>'11:00 pm', 'h:iA'=>'11:00PM',
172 'H.i'=>'23.00', 'h.ia'=>'11.00 pm', 'h.iA'=>'11.00PM' ) : $timeFormats,
173 'tmp_dir' => $tmp_dir, // this must be set!!
174 'translation_string_prefix' => empty($translation_string_prefix) ? false : $translation_string_prefix,
175 'unique_key' => empty($unique_key) ? md5(create_guid()) : $unique_key,
176 'upload_badext' => empty($upload_badext) ? array (
177 'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py',
178 'asp', 'cfm', 'js', 'vbs', 'html', 'htm' ) : $upload_badext,
179 'upload_dir' => $upload_dir, // this must be set!!
180 'upload_maxsize' => empty($upload_maxsize) ? 3000000 : $upload_maxsize,
181 'import_max_execution_time' => empty($import_max_execution_time) ? 3600 : $import_max_execution_time,
182 'lock_homepage' => false,
183 'lock_subpanels' => false,
184 'max_dashlets_homepage' => 15,
185 'dashlet_display_row_options' => array('1','3','5','10'),
186 'default_max_tabs' => empty($max_tabs) ? '7' : $max_tabs,
187 'default_subpanel_tabs' => empty($subpanel_tabs) ? true : $subpanel_tabs,
188 'default_subpanel_links' => empty($subpanel_links) ? false : $subpanel_links,
189 'default_swap_last_viewed' => empty($swap_last_viewed) ? false : $swap_last_viewed,
190 'default_swap_shortcuts' => empty($swap_shortcuts) ? false : $swap_shortcuts,
191 'default_navigation_paradigm' => empty($navigation_paradigm) ? 'gm' : $navigation_paradigm,
192 'default_call_status' => 'Planned',
193 'js_lang_version' => 1,
194 'passwordsetting' => empty($passwordsetting) ? array (
195 'SystemGeneratedPasswordON' => '',
196 'generatepasswordtmpl' => '',
197 'lostpasswordtmpl' => '',
198 'forgotpasswordON' => true,
199 'linkexpiration' => '1',
200 'linkexpirationtime' => '30',
201 'linkexpirationtype' => '1',
202 'systexpiration' => '0',
203 'systexpirationtime' => '',
204 'systexpirationtype' => '0',
205 'systexpirationlogin' => '',
206 ) : $passwordsetting,
210 function get_sugar_config_defaults() {
213 * used for getting base values for array style config.php. used by the
214 * installer and to fill in new entries on upgrades. see also:
218 $sugar_config_defaults = array (
219 'admin_export_only' => false,
220 'export_delimiter' => ',',
221 'cache_dir' => 'cache/',
222 'calculate_response_time' => true,
223 'create_default_user' => false,
224 'chartEngine' => 'Jit',
225 'date_formats' => array (
226 'Y-m-d' => '2010-12-23', 'm-d-Y' => '12-23-2010', 'd-m-Y' => '23-12-2010',
227 'Y/m/d' => '2010/12/23', 'm/d/Y' => '12/23/2010', 'd/m/Y' => '23/12/2010',
228 'Y.m.d' => '2010.12.23', 'd.m.Y' => '23.12.2010', 'm.d.Y' => '12.23.2010',),
229 'dbconfigoption' => array (
230 'persistent' => true,
233 'seqname_format' => '%s_seq',
236 'default_action' => 'index',
237 'default_charset' => return_session_value_or_default('default_charset',
239 'default_currency_name' => return_session_value_or_default('default_currency_name', 'US Dollar'),
240 'default_currency_symbol' => return_session_value_or_default('default_currency_symbol', '$'),
241 'default_currency_iso4217' => return_session_value_or_default('default_currency_iso4217', 'USD'),
242 'default_currency_significant_digits' => return_session_value_or_default('default_currency_significant_digits', 2),
243 'default_number_grouping_seperator' => return_session_value_or_default('default_number_grouping_seperator', ','),
244 'default_decimal_seperator' => return_session_value_or_default('default_decimal_seperator', '.'),
245 'default_date_format' => 'm/d/Y',
246 'default_export_charset' => 'UTF-8',
247 'default_language' => return_session_value_or_default('default_language',
249 'default_module' => 'Home',
250 'default_password' => '',
251 'default_permissions' => array (
257 'default_theme' => return_session_value_or_default('site_default_theme', 'Sugar5'),
258 'default_time_format' => 'h:ia',
259 'default_user_is_admin' => false,
260 'default_user_name' => '',
261 'disable_export' => false,
262 'disable_persistent_connections' =>
263 return_session_value_or_default('disable_persistent_connections',
265 'display_email_template_variable_chooser' => false,
266 'display_inbound_email_buttons' => false,
267 'dump_slow_queries' => false,
268 'email_default_editor' => 'html',
269 'email_default_client' => 'sugar',
270 'email_default_delete_attachments' => true,
271 'history_max_viewed' => 50,
272 'installer_locked' => true,
273 'import_max_records_per_file' => 100,
274 'languages' => array('en_us' => 'English (US)'),
275 'large_scale_test' => false,
276 'list_max_entries_per_page' => 20,
277 'list_max_entries_per_subpanel' => 10,
278 'lock_default_user_name' => false,
279 'log_memory_usage' => false,
280 'portal_view' => 'single_user',
281 'resource_management' => array (
282 'special_query_limit' => 50000,
283 'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'),
284 'default_limit' => 1000,
286 'require_accounts' => true,
287 'rss_cache_time' => return_session_value_or_default('rss_cache_time',
289 'save_query' => 'all',
290 'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable
291 'showThemePicker' => true,
292 'slow_query_time_msec' => '100',
294 'time_formats' => array (
295 'H:i'=>'23:00', 'h:ia'=>'11:00pm', 'h:iA'=>'11:00PM',
296 'H.i'=>'23.00', 'h.ia'=>'11.00pm', 'h.iA'=>'11.00PM' ),
297 'tracker_max_display_length' => 15,
298 'translation_string_prefix' =>
299 return_session_value_or_default('translation_string_prefix', false),
300 'upload_badext' => array (
301 'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py',
302 'asp', 'cfm', 'js', 'vbs', 'html', 'htm' ),
303 'upload_maxsize' => 3000000,
304 'import_max_execution_time' => 3600,
305 // 'use_php_code_json' => returnPhpJsonStatus(),
306 'verify_client_ip' => true,
307 'js_custom_version' => '',
308 'js_lang_version' => 1,
309 'default_number_grouping_seperator' => ',',
310 'default_decimal_seperator' => '.',
311 'lock_homepage' => false,
312 'lock_subpanels' => false,
313 'max_dashlets_homepage' => '15',
314 'default_max_tabs' => '7',
315 'dashlet_display_row_options' => array('1','3','5','10'),
316 'default_subpanel_tabs' => true,
317 'default_subpanel_links' => false,
318 'default_swap_last_viewed' => false,
319 'default_swap_shortcuts' => false,
320 'default_navigation_paradigm' => 'gm',
321 'admin_access_control' => false,
322 'use_common_ml_dir' => false,
323 'common_ml_dir' => '',
325 'passwordsetting' => empty($passwordsetting) ? array (
326 'SystemGeneratedPasswordON' => '',
327 'generatepasswordtmpl' => '',
328 'lostpasswordtmpl' => '',
329 'forgotpasswordON' => false,
330 'linkexpiration' => '1',
331 'linkexpirationtime' => '30',
332 'linkexpirationtype' => '1',
333 'systexpiration' => '0',
334 'systexpirationtime' => '',
335 'systexpirationtype' => '0',
336 'systexpirationlogin' => '',
337 ) : $passwordsetting,
338 'use_real_names' => true,
341 if(!is_object($locale)) {
342 $locale = new Localization();
345 $sugar_config_defaults['default_currencies'] = $locale->getDefaultCurrencies();
347 $sugar_config_defaults = sugarArrayMerge($locale->getLocaleConfigDefaults(), $sugar_config_defaults);
348 return( $sugar_config_defaults );
352 * @deprecated use SugarView::getMenu() instead
354 function load_menu($path){
357 if(file_exists($path . 'Menu.php'))
359 require($path . 'Menu.php');
361 if(file_exists('custom/' . $path . 'Ext/Menus/menu.ext.php'))
363 require('custom/' . $path . 'Ext/Menus/menu.ext.php');
365 if(file_exists('custom/application/Ext/Menus/menu.ext.php'))
367 require('custom/application/Ext/Menus/menu.ext.php');
373 * get_notify_template_file
374 * This function will return the location of the email notifications template to use
376 * @return string relative file path to email notifications template file
378 function get_notify_template_file($language){
380 * Order of operation:
381 * 1) custom version of specified language
382 * 2) stock version of specified language
383 * 3) custom version of en_us template
384 * 4) stock en_us template
387 // set $file to the base code template so it's set if none of the conditions pass
388 $file = "include/language/en_us.notify_template.html";
390 if(file_exists("custom/include/language/{$language}.notify_template.html")){
391 $file = "custom/include/language/{$language}.notify_template.html";
393 else if(file_exists("include/language/{$language}.notify_template.html")){
394 $file = "include/language/{$language}.notify_template.html";
396 else if(file_exists("custom/include/language/en_us.notify_template.html")){
397 $file = "custom/include/language/en_us.notify_template.html";
403 function sugar_config_union( $default, $override ){
404 // a little different then array_merge and array_merge_recursive. we want
405 // the second array to override the first array if the same value exists,
406 // otherwise merge the unique keys. it handles arrays of arrays recursively
407 // might be suitable for a generic array_union
408 if( !is_array( $override ) ){
411 foreach( $default as $key => $value ){
412 if( !array_key_exists($key, $override) ){
413 $override[$key] = $value;
415 else if( is_array( $key ) ){
416 $override[$key] = sugar_config_union( $value, $override[$key] );
422 function make_not_writable( $file ){
423 // Returns true if the given file/dir has been made not writable
425 if( is_file($file) || is_dir($file) ){
426 if( !is_writable($file) ){
430 $original_fileperms = fileperms($file);
432 // take away writable permissions
433 $new_fileperms = $original_fileperms & ~0x0092;
434 @sugar_chmod($file, $new_fileperms);
436 if( !is_writable($file) ){
445 /** This function returns the name of the person.
446 * It currently returns "first last". It should not put the space if either name is not available.
447 * It should not return errors if either name is not available.
448 * If no names are present, it will return ""
449 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
450 * All Rights Reserved.
451 * Contributor(s): ______________________________________..
453 function return_name($row, $first_column, $last_column)
459 if(isset($row[$first_column]))
461 $first_name = stripslashes($row[$first_column]);
464 if(isset($row[$last_column]))
466 $last_name = stripslashes($row[$last_column]);
469 $full_name = $first_name;
471 // If we have a first name and we have a last name
472 if($full_name != "" && $last_name != "")
474 // append a space, then the last name
475 $full_name .= " ".$last_name;
477 // If we have no first name, but we have a last name
478 else if($last_name != "")
480 // append the last name without the space.
481 $full_name .= $last_name;
488 function get_languages()
490 global $sugar_config;
491 $lang = $sugar_config['languages'];
492 if(!empty($sugar_config['disabled_languages'])){
493 foreach(explode(',', $sugar_config['disabled_languages']) as $disable) {
494 unset($lang[$disable]);
500 function get_all_languages()
502 global $sugar_config;
503 return $sugar_config['languages'];
507 function get_language_display($key)
509 global $sugar_config;
510 return $sugar_config['languages'][$key];
513 function get_assigned_user_name($assigned_user_id, $is_group = '') {
514 static $saved_user_list = null;
516 if(empty($saved_user_list)) {
517 $saved_user_list = get_user_array(false, '', '', false, null, $is_group);
520 if(isset($saved_user_list[$assigned_user_id])) {
521 return $saved_user_list[$assigned_user_id];
528 * retrieves the user_name column value (login)
529 * @param string id GUID of user
532 function get_user_name($id) {
536 $db = DBManagerFactory::getInstance();
538 $q = "SELECT user_name FROM users WHERE id='{$id}'";
540 $a = $db->fetchByAssoc($r);
542 return (empty($a)) ? '' : $a['user_name'];
546 //TODO Update to use global cache
547 function get_user_array($add_blank=true, $status="Active", $assigned_user="", $use_real_name=false, $user_name_begins = null, $is_group=' AND portal_only=0 ', $from_cache = true) {
549 global $sugar_config;
553 $locale = new Localization();
556 $user_array = get_register_value('user_array', $add_blank. $status . $assigned_user);
558 if(!isset($user_array)) {
559 $db = DBManagerFactory::getInstance();
560 $temp_result = Array();
561 // Including deleted users for now.
562 if (empty($status)) {
563 $query = "SELECT id, first_name, last_name, user_name from users WHERE 1=1".$is_group;
566 $query = "SELECT id, first_name, last_name, user_name from users WHERE status='$status'".$is_group;
569 if (!empty($user_name_begins)) {
570 $query .= " AND user_name LIKE '$user_name_begins%' ";
572 if (!empty($assigned_user)) {
573 $query .= " OR id='$assigned_user'";
575 $query = $query.' ORDER BY user_name ASC';
576 $GLOBALS['log']->debug("get_user_array query: $query");
577 $result = $db->query($query, true, "Error filling in user array: ");
579 if ($add_blank==true) {
580 // Add in a blank row
581 $temp_result[''] = '';
584 // Get the id and the name.
585 while($row = $db->fetchByAssoc($result)) {
586 if($use_real_name == true || showFullName()) {
587 if(isset($row['last_name'])) { // cn: we will ALWAYS have both first_name and last_name (empty value if blank in db)
588 $temp_result[$row['id']] = $locale->getLocaleFormattedName($row['first_name'],$row['last_name']);
590 $temp_result[$row['id']] = $row['user_name'];
593 $temp_result[$row['id']] = $row['user_name'];
597 $user_array = $temp_result;
599 set_register_value('user_array', $add_blank. $status . $assigned_user, $temp_result);
608 * uses a different query to return a list of users than get_user_array()
609 * @param args string where clause entry
610 * @return array Array of Users' details that match passed criteria
612 function getUserArrayFromFullName($args, $hide_portal_users = false) {
614 $db = DBManagerFactory::getInstance();
617 if(strpos($args, " ")) {
618 $argArray = explode(" ", $args);
624 foreach($argArray as $arg) {
625 if(!empty($inClause)) {
631 $inClause .= "(first_name LIKE '{$arg}%' OR last_name LIKE '{$arg}%')";
634 $query = "SELECT id, first_name, last_name, user_name FROM users WHERE status='Active' AND deleted=0 AND ";
635 if ( $hide_portal_users ) {
636 $query .= " portal_only=0 AND ";
639 $query .= " ORDER BY last_name ASC";
641 $r = $db->query($query);
643 while($a = $db->fetchByAssoc($r)) {
644 $ret[$a['id']] = $locale->getLocaleFormattedName($a['first_name'], $a['last_name']);
652 * based on user pref then system pref
654 function showFullName() {
655 global $sugar_config;
656 global $current_user;
657 static $showFullName = null;
659 if (is_null($showFullName)) {
660 $sysPref = (isset($sugar_config['use_real_names']) && $sugar_config['use_real_names'] == true) ? true : false;
661 $userPref = (is_object($current_user)) ? $current_user->getPreference('use_real_names') : null;
663 if($userPref != null) {
664 $bool = ($userPref == 'on') ? true : false;
665 $showFullName = $bool;
667 $showFullName = $sysPref;
671 return $showFullName;
674 function clean($string, $maxLength)
676 $string = substr($string, 0, $maxLength);
677 return escapeshellcmd($string);
681 * Copy the specified request variable to the member variable of the specified object.
682 * Do no copy if the member variable is already set.
683 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
684 * All Rights Reserved.
685 * Contributor(s): ______________________________________..
687 function safe_map($request_var, & $focus, $always_copy = false)
689 safe_map_named($request_var, $focus, $request_var, $always_copy);
693 * Copy the specified request variable to the member variable of the specified object.
694 * Do no copy if the member variable is already set.
695 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
696 * All Rights Reserved.
697 * Contributor(s): ______________________________________..
699 function safe_map_named($request_var, & $focus, $member_var, $always_copy)
701 if (isset($_REQUEST[$request_var]) && ($always_copy || is_null($focus->$member_var))) {
702 $GLOBALS['log']->debug("safe map named called assigning '{$_REQUEST[$request_var]}' to $member_var");
703 $focus->$member_var = $_REQUEST[$request_var];
708 * This function retrieves an application language file and returns the array of strings included in the $app_list_strings var.
710 * @param string $language specific language to load
711 * @return array lang strings
713 function return_app_list_strings_language($language)
715 global $app_list_strings;
716 global $sugar_config;
718 $cache_key = 'app_list_strings.'.$language;
720 // Check for cached value
721 $cache_entry = sugar_cache_retrieve($cache_key);
722 if(!empty($cache_entry))
727 $default_language = $sugar_config['default_language'];
728 $temp_app_list_strings = $app_list_strings;
731 if ($language != 'en_us') {
734 if ($default_language != 'en_us' && $language != $default_language) {
735 $langs[] = $default_language;
737 $langs[] = $language;
739 $app_list_strings_array = array();
741 foreach ( $langs as $lang ) {
742 $app_list_strings = array();
743 if(file_exists("include/language/$lang.lang.php")) {
744 include("include/language/$lang.lang.php");
745 $GLOBALS['log']->info("Found language file: $lang.lang.php");
747 if(file_exists("include/language/$lang.lang.override.php")) {
748 include("include/language/$lang.lang.override.php");
749 $GLOBALS['log']->info("Found override language file: $lang.lang.override.php");
751 if(file_exists("include/language/$lang.lang.php.override")) {
752 include("include/language/$lang.lang.php.override");
753 $GLOBALS['log']->info("Found override language file: $lang.lang.php.override");
756 $app_list_strings_array[] = $app_list_strings;
759 $app_list_strings = array();
760 foreach ( $app_list_strings_array as $app_list_strings_item ) {
761 $app_list_strings = sugarArrayMerge($app_list_strings, $app_list_strings_item);
764 foreach ( $langs as $lang ) {
765 if(file_exists("custom/application/Ext/Language/$lang.lang.ext.php")) {
766 $app_list_strings = _mergeCustomAppListStrings("custom/application/Ext/Language/$lang.lang.ext.php" , $app_list_strings);
767 $GLOBALS['log']->info("Found extended language file: $lang.lang.ext.php");
769 if(file_exists("custom/include/language/$lang.lang.php")) {
770 include("custom/include/language/$lang.lang.php");
771 $GLOBALS['log']->info("Found custom language file: $lang.lang.php");
775 if(!isset($app_list_strings)) {
776 $GLOBALS['log']->fatal("Unable to load the application language file for the selected language ($language) or the default language ($default_language) or the en_us language");
780 $return_value = $app_list_strings;
781 $app_list_strings = $temp_app_list_strings;
783 sugar_cache_put($cache_key, $return_value);
785 return $return_value;
789 * The dropdown items in custom language files is $app_list_strings['$key']['$second_key'] = $value not
790 * $GLOBALS['app_list_strings']['$key'] = $value, so we have to delete the original ones in app_list_strings and relace it with the custom ones.
791 * @param file string the language that you want include,
792 * @param app_list_strings array the golbal strings
796 function _mergeCustomAppListStrings($file , $app_list_strings){
797 $app_list_strings_original = $app_list_strings;
798 unset($app_list_strings);
800 if(!isset($app_list_strings) || !is_array($app_list_strings)){
801 return $app_list_strings_original;
803 //Bug 25347: We should not merge custom dropdown fields unless they relate to parent fields or the module list.
804 foreach($app_list_strings as $key=>$value)
806 $exemptDropdowns = array("moduleList", "parent_type_display", "record_type_display", "record_type_display_notes");
807 if (!in_array($key, $exemptDropdowns) && array_key_exists($key, $app_list_strings_original))
809 unset($app_list_strings_original["$key"]);
812 $app_list_strings = sugarArrayMergeRecursive($app_list_strings_original , $app_list_strings);
813 return $app_list_strings;
817 * This function retrieves an application language file and returns the array of strings included.
819 * @param string $language specific language to load
820 * @return array lang strings
822 function return_application_language($language)
824 global $app_strings, $sugar_config;
826 $cache_key = 'app_strings.'.$language;
828 // Check for cached value
829 $cache_entry = sugar_cache_retrieve($cache_key);
830 if(!empty($cache_entry))
835 $temp_app_strings = $app_strings;
836 $default_language = $sugar_config['default_language'];
839 if ($language != 'en_us') {
842 if ($default_language != 'en_us' && $language != $default_language) {
843 $langs[] = $default_language;
846 $langs[] = $language;
848 $app_strings_array = array();
850 foreach ( $langs as $lang ) {
851 $app_strings = array();
852 if(file_exists("include/language/$lang.lang.php")) {
853 include("include/language/$lang.lang.php");
854 $GLOBALS['log']->info("Found language file: $lang.lang.php");
856 if(file_exists("include/language/$lang.lang.override.php")) {
857 include("include/language/$lang.lang.override.php");
858 $GLOBALS['log']->info("Found override language file: $lang.lang.override.php");
860 if(file_exists("include/language/$lang.lang.php.override")) {
861 include("include/language/$lang.lang.php.override");
862 $GLOBALS['log']->info("Found override language file: $lang.lang.php.override");
864 if(file_exists("custom/application/Ext/Language/$lang.lang.ext.php")) {
865 include("custom/application/Ext/Language/$lang.lang.ext.php");
866 $GLOBALS['log']->info("Found extended language file: $lang.lang.ext.php");
868 if(file_exists("custom/include/language/$lang.lang.php")) {
869 include("custom/include/language/$lang.lang.php");
870 $GLOBALS['log']->info("Found custom language file: $lang.lang.php");
872 $app_strings_array[] = $app_strings;
875 $app_strings = array();
876 foreach ( $app_strings_array as $app_strings_item ) {
877 $app_strings = sugarArrayMerge($app_strings, $app_strings_item);
880 if(!isset($app_strings)) {
881 $GLOBALS['log']->fatal("Unable to load the application language strings");
885 // If we are in debug mode for translating, turn on the prefix now!
886 if($sugar_config['translation_string_prefix']) {
887 foreach($app_strings as $entry_key=>$entry_value) {
888 $app_strings[$entry_key] = $language.' '.$entry_value;
891 if(isset($_SESSION['show_deleted'])) {
892 $app_strings['LBL_DELETE_BUTTON'] = $app_strings['LBL_UNDELETE_BUTTON'];
893 $app_strings['LBL_DELETE_BUTTON_LABEL'] = $app_strings['LBL_UNDELETE_BUTTON_LABEL'];
894 $app_strings['LBL_DELETE_BUTTON_TITLE'] = $app_strings['LBL_UNDELETE_BUTTON_TITLE'];
895 $app_strings['LBL_DELETE'] = $app_strings['LBL_UNDELETE'];
898 $app_strings['LBL_ALT_HOT_KEY'] = get_alt_hot_key();
900 $return_value = $app_strings;
901 $app_strings = $temp_app_strings;
903 sugar_cache_put($cache_key, $return_value);
905 return $return_value;
909 * This function retrieves a module's language file and returns the array of strings included.
911 * @param string $language specific language to load
912 * @param string $module module name to load strings for
913 * @param bool $refresh optional, true if you want to rebuild the language strings
914 * @return array lang strings
916 function return_module_language($language, $module, $refresh=false)
919 global $sugar_config;
920 global $currentModule;
922 // Jenny - Bug 8119: Need to check if $module is not empty
923 if (empty($module)) {
924 $stack = debug_backtrace();
925 $GLOBALS['log']->warn("Variable module is not in return_module_language ". var_export($stack, true));
929 $cache_key = LanguageManager::getLanguageCacheKey($module, $language);
930 // Check for cached value
931 $cache_entry = sugar_cache_retrieve($cache_key);
932 if(!empty($cache_entry))
937 // Store the current mod strings for later
938 $temp_mod_strings = $mod_strings;
939 $loaded_mod_strings = array();
940 $language_used = $language;
941 $default_language = $sugar_config['default_language'];
943 if(empty($language)) {
944 $language = $default_language;
947 // Bug 21559 - So we can get all the strings defined in the template, refresh
948 // the vardefs file if the cached language file doesn't exist.
949 if(!file_exists($GLOBALS['sugar_config']['cache_dir'].'modules/'. $module . '/language/'.$language.'.lang.php')
950 && !empty($GLOBALS['beanList'][$module])){
951 $object = $GLOBALS['beanList'][$module];
952 if ($object == 'aCase') {
955 VardefManager::refreshVardefs($module,$object);
958 $loaded_mod_strings = LanguageManager::loadModuleLanguage($module, $language,$refresh);
960 // cn: bug 6048 - merge en_us with requested language
961 if($language != $sugar_config['default_language'])
962 $loaded_mod_strings = sugarArrayMerge(
963 LanguageManager::loadModuleLanguage($module, $sugar_config['default_language'],$refresh),
967 // Load in en_us strings by default
968 if($language != 'en_us' && $sugar_config['default_language'] != 'en_us')
969 $loaded_mod_strings = sugarArrayMerge(
970 LanguageManager::loadModuleLanguage($module, 'en_us', $refresh),
974 // If we are in debug mode for translating, turn on the prefix now!
975 if($sugar_config['translation_string_prefix']) {
976 foreach($loaded_mod_strings as $entry_key=>$entry_value) {
977 $loaded_mod_strings[$entry_key] = $language_used.' '.$entry_value;
981 $return_value = $loaded_mod_strings;
982 if(!isset($mod_strings)){
983 $mod_strings = $return_value;
986 $mod_strings = $temp_mod_strings;
988 sugar_cache_put($cache_key, $return_value);
989 return $return_value;
993 /** This function retrieves an application language file and returns the array of strings included in the $mod_list_strings var.
994 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
995 * All Rights Reserved.
996 * Contributor(s): ______________________________________..
997 * If you are using the current language, do not call this function unless you are loading it for the first time */
998 function return_mod_list_strings_language($language,$module) {
999 global $mod_list_strings;
1000 global $sugar_config;
1001 global $currentModule;
1003 $cache_key = "mod_list_str_lang.".$language.$module;
1005 // Check for cached value
1006 $cache_entry = sugar_cache_retrieve($cache_key);
1007 if(!empty($cache_entry))
1009 return $cache_entry;
1012 $language_used = $language;
1013 $temp_mod_list_strings = $mod_list_strings;
1014 $default_language = $sugar_config['default_language'];
1016 if($currentModule == $module && isset($mod_list_strings) && $mod_list_strings != null) {
1017 return $mod_list_strings;
1020 // cn: bug 6351 - include en_us if file langpack not available
1021 // cn: bug 6048 - merge en_us with requested language
1022 include("modules/$module/language/en_us.lang.php");
1023 $en_mod_list_strings = array();
1024 if($language_used != $default_language)
1025 $en_mod_list_strings = $mod_list_strings;
1027 if(file_exists("modules/$module/language/$language.lang.php")) {
1028 include("modules/$module/language/$language.lang.php");
1031 if(file_exists("modules/$module/language/$language.lang.override.php")){
1032 include("modules/$module/language/$language.lang.override.php");
1035 if(file_exists("modules/$module/language/$language.lang.php.override")){
1036 echo 'Please Change:<br>' . "modules/$module/language/$language.lang.php.override" . '<br>to<br>' . 'Please Change:<br>' . "modules/$module/language/$language.lang.override.php";
1037 include("modules/$module/language/$language.lang.php.override");
1040 // cn: bug 6048 - merge en_us with requested language
1041 $mod_list_strings = sugarArrayMerge($en_mod_list_strings, $mod_list_strings);
1043 // if we still don't have a language pack, then log an error
1044 if(!isset($mod_list_strings)) {
1045 $GLOBALS['log']->fatal("Unable to load the application list language file for the selected language($language) or the default language($default_language) for module({$module})");
1049 $return_value = $mod_list_strings;
1050 $mod_list_strings = $temp_mod_list_strings;
1052 sugar_cache_put($cache_key, $return_value);
1053 return $return_value;
1057 /** This function retrieves a theme's language file and returns the array of strings included.
1058 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1059 * All Rights Reserved.
1060 * Contributor(s): ______________________________________..
1062 function return_theme_language($language, $theme)
1064 global $mod_strings, $sugar_config, $currentModule;
1066 $language_used = $language;
1067 $default_language = $sugar_config['default_language'];
1069 include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php");
1070 if(file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php")){
1071 include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php");
1073 if(file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override")){
1074 echo 'Please Change:<br>' . SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override" . '<br>to<br>' . 'Please Change:<br>' . SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php";
1075 include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override");
1077 if(!isset($theme_strings))
1079 $GLOBALS['log']->warn("Unable to find the theme file for language: ".$language." and theme: ".$theme);
1080 require(SugarThemeRegistry::get($theme)->getFilePath()."/language/$default_language.lang.php");
1081 $language_used = $default_language;
1084 if(!isset($theme_strings))
1086 $GLOBALS['log']->fatal("Unable to load the theme($theme) language file for the selected language($language) or the default language($default_language)");
1090 // If we are in debug mode for translating, turn on the prefix now!
1091 if($sugar_config['translation_string_prefix'])
1093 foreach($theme_strings as $entry_key=>$entry_value)
1095 $theme_strings[$entry_key] = $language_used.' '.$entry_value;
1099 return $theme_strings;
1104 /** If the session variable is defined and is not equal to "" then return it. Otherwise, return the default value.
1105 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1106 * All Rights Reserved.
1107 * Contributor(s): ______________________________________..
1109 function return_session_value_or_default($varname, $default)
1111 if(isset($_SESSION[$varname]) && $_SESSION[$varname] != "")
1113 return $_SESSION[$varname];
1120 * Creates an array of where restrictions. These are used to construct a where SQL statement on the query
1121 * It looks for the variable in the $_REQUEST array. If it is set and is not "" it will create a where clause out of it.
1122 * @param &$where_clauses - The array to append the clause to
1123 * @param $variable_name - The name of the variable to look for an add to the where clause if found
1124 * @param $SQL_name - [Optional] If specified, this is the SQL column name that is used. If not specified, the $variable_name is used as the SQL_name.
1125 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1126 * All Rights Reserved.
1127 * Contributor(s): ______________________________________..
1129 function append_where_clause(&$where_clauses, $variable_name, $SQL_name = null)
1131 if($SQL_name == null)
1133 $SQL_name = $variable_name;
1136 if(isset($_REQUEST[$variable_name]) && $_REQUEST[$variable_name] != "")
1138 array_push($where_clauses, "$SQL_name like '".$GLOBALS['db']->quote($_REQUEST[$variable_name])."%'");
1143 * Generate the appropriate SQL based on the where clauses.
1144 * @param $where_clauses - An Array of individual where clauses stored as strings
1145 * @returns string where_clause - The final SQL where clause to be executed.
1146 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1147 * All Rights Reserved.
1148 * Contributor(s): ______________________________________..
1150 function generate_where_statement($where_clauses)
1153 foreach($where_clauses as $clause)
1160 $GLOBALS['log']->info("Here is the where clause for the list view: $where");
1165 * determines if a passed string matches the criteria for a Sugar GUID
1166 * @param string $guid
1167 * @return bool False on failure
1169 function is_guid($guid) {
1170 if(strlen($guid) != 36) {
1174 if(preg_match("/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/i", $guid)) {
1183 * A temporary method of generating GUIDs of the correct format for our DB.
1184 * @return String contianing a GUID in the format: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
1186 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1187 * All Rights Reserved.
1188 * Contributor(s): ______________________________________..
1190 function create_guid()
1192 $microTime = microtime();
1193 list($a_dec, $a_sec) = explode(" ", $microTime);
1195 $dec_hex = dechex($a_dec* 1000000);
1196 $sec_hex = dechex($a_sec);
1198 ensure_length($dec_hex, 5);
1199 ensure_length($sec_hex, 6);
1203 $guid .= create_guid_section(3);
1205 $guid .= create_guid_section(4);
1207 $guid .= create_guid_section(4);
1209 $guid .= create_guid_section(4);
1212 $guid .= create_guid_section(6);
1218 function create_guid_section($characters)
1221 for($i=0; $i<$characters; $i++)
1223 $return .= dechex(mt_rand(0,15));
1228 function ensure_length(&$string, $length)
1230 $strlen = strlen($string);
1231 if($strlen < $length)
1233 $string = str_pad($string,$length,"0");
1235 else if($strlen > $length)
1237 $string = substr($string, 0, $length);
1241 function microtime_diff($a, $b) {
1242 list($a_dec, $a_sec) = explode(" ", $a);
1243 list($b_dec, $b_sec) = explode(" ", $b);
1244 return $b_sec - $a_sec + $b_dec - $a_dec;
1247 // check if Studio is displayed.
1248 function displayStudioForCurrentUser()
1250 if ( is_admin($GLOBALS['current_user']) ) {
1260 function displayWorkflowForCurrentUser()
1262 $_SESSION['display_workflow_for_user'] = false;
1266 // return an array with all modules where the user is an admin.
1267 function get_admin_modules_for_user($user) {
1269 $admin_modules = array();
1271 return ($admin_modules);
1274 function get_workflow_admin_modules_for_user($user){
1275 if (isset($_SESSION['get_workflow_admin_modules_for_user'])) {
1276 return $_SESSION['get_workflow_admin_modules_for_user'];
1280 $workflow_mod_list = array();
1281 foreach($moduleList as $module){
1282 $workflow_mod_list[$module] = $module;
1285 // This list is taken from teh previous version of workflow_utils.php
1286 $workflow_mod_list['Tasks'] = "Tasks";
1287 $workflow_mod_list['Calls'] = "Calls";
1288 $workflow_mod_list['Meetings'] = "Meetings";
1289 $workflow_mod_list['Notes'] = "Notes";
1290 $workflow_mod_list['ProjectTask'] = "Project Tasks";
1291 $workflow_mod_list['Leads'] = "Leads";
1292 $workflow_mod_list['Opportunities'] = "Opportunities";
1295 $workflow_admin_modules = array();
1297 return $workflow_admin_modules;
1299 $actions = ACLAction::getUserActions($user->id);
1300 //check for ForecastSchedule because it doesn't exist in $workflow_mod_list
1301 if (isset($actions['ForecastSchedule']['module']['admin']['aclaccess']) && ($actions['ForecastSchedule']['module']['admin']['aclaccess']==ACL_ALLOW_DEV ||
1302 $actions['ForecastSchedule']['module']['admin']['aclaccess']==ACL_ALLOW_ADMIN_DEV)) {
1303 $workflow_admin_modules['Forecasts'] = 'Forecasts';
1305 foreach ($workflow_mod_list as $key=>$val) {
1306 if(!in_array($val, $workflow_admin_modules) && ($val!='iFrames' && $val!='Feeds' && $val!='Home' && $val!='Dashboard'
1307 && $val!='Calendar' && $val!='Activities' && $val!='Reports') &&
1308 (is_admin_for_module($user,$key))) {
1309 $workflow_admin_modules[$key] = $val;
1312 $_SESSION['get_workflow_admin_modules_for_user'] = $workflow_admin_modules;
1313 return ($workflow_admin_modules);
1316 // Check if user is admin for at least one module.
1317 function is_admin_for_any_module($user) {
1322 // Check if user is admin for a specific module.
1323 function is_admin_for_module($user,$module) {
1329 * Check if user id belongs to a system admin.
1330 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1331 * All Rights Reserved.
1332 * Contributor(s): ______________________________________..
1334 function is_admin($user) {
1335 if(!empty($user) && ($user->is_admin == '1' || $user->is_admin === 'on')){
1343 * Return the display name for a theme if it exists.
1344 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1345 * All Rights Reserved.
1346 * Contributor(s): ______________________________________..
1348 * @deprecated use SugarThemeRegistry::get($theme)->name instead
1350 function get_theme_display($theme)
1352 return SugarThemeRegistry::get($theme)->name;
1356 * Return an array of directory names.
1357 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1358 * All Rights Reserved.
1359 * Contributor(s): ______________________________________..
1361 * @deprecated use SugarThemeRegistry::availableThemes() instead.
1363 function get_themes()
1365 return SugarThemeRegistry::availableThemes();
1369 * THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED; USE get_select_options_with_id()
1370 * Create HTML to display select options in a dropdown list. To be used inside
1371 * of a select statement in a form.
1372 * param $option_list - the array of strings to that contains the option list
1373 * param $selected - the string which contains the default value
1374 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1375 * All Rights Reserved.
1376 * Contributor(s): ______________________________________..
1378 function get_select_options ($option_list, $selected) {
1379 return get_select_options_with_id($option_list, $selected);
1383 * Create HTML to display select options in a dropdown list. To be used inside
1384 * of a select statement in a form. This method expects the option list to have keys and values. The keys are the ids. The values are the display strings.
1385 * param $option_list - the array of strings to that contains the option list
1386 * param $selected - the string which contains the default value
1387 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1388 * All Rights Reserved.
1389 * Contributor(s): ______________________________________..
1391 function get_select_options_with_id ($option_list, $selected_key) {
1392 return get_select_options_with_id_separate_key($option_list, $option_list, $selected_key);
1397 * Create HTML to display select options in a dropdown list. To be used inside
1398 * of a select statement in a form. This method expects the option list to have keys and values. The keys are the ids. The values are the display strings.
1399 * param $label_list - the array of strings to that contains the option list
1400 * param $key_list - the array of strings to that contains the values list
1401 * param $selected - the string which contains the default value
1402 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1403 * All Rights Reserved.
1404 * Contributor(s): ______________________________________..
1406 function get_select_options_with_id_separate_key ($label_list, $key_list, $selected_key, $massupdate=false) {
1407 global $app_strings;
1408 $select_options = "";
1410 //for setting null selection values to human readable --None--
1411 $pattern = "/'0?'></";
1412 $replacement = "''>".$app_strings['LBL_NONE']."<";
1414 if (empty($key_list)) $key_list = array();
1415 //create the type dropdown domain and set the selected value if $opp value already exists
1416 foreach ($key_list as $option_key=>$option_value) {
1418 $selected_string = '';
1419 // the system is evaluating $selected_key == 0 || '' to true. Be very careful when changing this. Test all cases.
1420 // The bug was only happening with one of the users in the drop down. It was being replaced by none.
1421 if (($option_key != '' && $selected_key == $option_key) || ($selected_key == '' && $option_key == '' && !$massupdate) || (is_array($selected_key) && in_array($option_key, $selected_key)))
1423 $selected_string = 'selected ';
1426 $html_value = $option_key;
1428 $select_options .= "\n<OPTION ".$selected_string."value='$html_value'>$label_list[$option_key]</OPTION>";
1430 $select_options = preg_replace($pattern, $replacement, $select_options);
1431 return $select_options;
1436 * Call this method instead of die().
1437 * Then we call the die method with the error message that is passed in.
1439 function sugar_die($error_message)
1443 die($error_message);
1448 * Create javascript to clear values of all elements in a form.
1449 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1450 * All Rights Reserved.
1451 * Contributor(s): ______________________________________..
1453 function get_clear_form_js () {
1454 $the_script = <<<EOQ
1455 <script type="text/javascript" language="JavaScript">
1456 function clear_form(form) {
1457 var newLoc = 'index.php?action=' + form.action.value + '&module=' + form.module.value + '&query=true&clear_query=true';
1458 if(typeof(form.advanced) != 'undefined'){
1459 newLoc += '&advanced=' + form.advanced.value;
1461 document.location.href= newLoc;
1470 * Create javascript to set the cursor focus to specific field in a form
1471 * when the screen is rendered. The field name is currently hardcoded into the
1473 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1474 * All Rights Reserved.
1475 * Contributor(s): ______________________________________..
1477 function get_set_focus_js () {
1478 //TODO Clint 5/20 - Make this function more generic so that it can take in the target form and field names as variables
1479 $the_script = <<<EOQ
1480 <script type="text/javascript" language="JavaScript">
1482 function set_focus() {
1483 if (document.forms.length > 0) {
1484 for (i = 0; i < document.forms.length; i++) {
1485 for (j = 0; j < document.forms[i].elements.length; j++) {
1486 var field = document.forms[i].elements[j];
1487 if ((field.type == "text" || field.type == "textarea" || field.type == "password") &&
1488 !field.disabled && (field.name == "first_name" || field.name == "name" || field.name == "user_name" || field.name=="document_name")) {
1490 if (field.type == "text") {
1507 * Very cool algorithm for sorting multi-dimensional arrays. Found at http://us2.php.net/manual/en/function.array-multisort.php
1508 * Syntax: $new_array = array_csort($array [, 'col1' [, SORT_FLAG [, SORT_FLAG]]]...);
1509 * Explanation: $array is the array you want to sort, 'col1' is the name of the column
1510 * you want to sort, SORT_FLAGS are : SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
1511 * you can repeat the 'col',FLAG,FLAG, as often you want, the highest prioritiy is given to
1512 * the first - so the array is sorted by the last given column first, then the one before ...
1513 * Example: $array = array_csort($array,'town','age',SORT_DESC,'name');
1514 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1515 * All Rights Reserved.
1516 * Contributor(s): ______________________________________..
1518 function array_csort() {
1519 $args = func_get_args();
1520 $marray = array_shift($args);
1523 $msortline = "return(array_multisort(";
1524 foreach ($args as $arg) {
1526 if (is_string($arg)) {
1527 foreach ($marray as $row) {
1528 $sortarr[$i][] = $row[$arg];
1531 $sortarr[$i] = $arg;
1533 $msortline .= "\$sortarr[".$i."],";
1535 $msortline .= "\$marray));";
1542 * Converts localized date format string to jscalendar format
1543 * Example: $array = array_csort($array,'town','age',SORT_DESC,'name');
1544 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1545 * All Rights Reserved.
1546 * Contributor(s): ______________________________________..
1548 function parse_calendardate($local_format) {
1549 preg_match('/\(?([^-]{1})[^-]*-([^-]{1})[^-]*-([^-]{1})[^-]*\)/', $local_format, $matches);
1550 $calendar_format = "%" . $matches[1] . "-%" . $matches[2] . "-%" . $matches[3];
1551 return str_replace(array("y", "ᅣ1�7", "a", "j"), array("Y", "Y", "Y", "d"), $calendar_format);
1558 function translate($string, $mod='', $selectedValue=''){
1559 //$test_start = microtime();
1560 //static $mod_strings_results = array();
1562 global $current_language;
1564 if(isset($_REQUEST['login_language'])){
1565 $current_language = ($_REQUEST['login_language'] == $current_language)? $current_language : $_REQUEST['login_language'];
1567 $mod_strings = return_module_language($current_language, $mod);
1570 global $mod_strings;
1574 global $app_strings, $app_list_strings;
1576 if(isset($mod_strings[$string]))
1577 $returnValue = $mod_strings[$string];
1578 else if(isset($app_strings[$string]))
1579 $returnValue = $app_strings[$string];
1580 else if(isset($app_list_strings[$string]))
1581 $returnValue = $app_list_strings[$string];
1582 else if(isset($app_list_strings['moduleList']) && isset($app_list_strings['moduleList'][$string]))
1583 $returnValue = $app_list_strings['moduleList'][$string];
1586 //$test_end = microtime();
1588 // $mod_strings_results[$mod] = microtime_diff($test_start,$test_end);
1590 // echo("translate results:");
1592 // $total_strings = 0;
1593 // foreach($mod_strings_results as $key=>$value)
1595 // echo("Module $key \t\t time $value \t\t<br>");
1596 // $total_time += $value;
1599 // echo("Total time: $total_time<br>");
1603 if(empty($returnValue)){
1607 if(is_array($returnValue) && ! empty($selectedValue) && isset($returnValue[$selectedValue]) ){
1608 return $returnValue[$selectedValue];
1611 return $returnValue;
1614 function unTranslateNum($num) {
1616 static $num_grp_sep;
1617 global $current_user, $sugar_config;
1619 if($dec_sep == null) {
1620 $user_dec_sep = $current_user->getPreference('dec_sep');
1621 $dec_sep = (empty($user_dec_sep) ? $sugar_config['default_decimal_seperator'] : $user_dec_sep);
1623 if($num_grp_sep == null) {
1624 $user_num_grp_sep = $current_user->getPreference('num_grp_sep');
1625 $num_grp_sep = (empty($user_num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $user_num_grp_sep);
1628 $num = preg_replace("'" . preg_quote($num_grp_sep) . "'", '', $num);
1629 $num = preg_replace("'" . preg_quote($dec_sep) . "'", '.', $num);
1634 function add_http($url) {
1635 if(!preg_match("@://@i", $url)) {
1637 if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
1641 return "{$scheme}://{$url}";
1648 * returns a default array of XSS tags to clean
1651 function getDefaultXssTags() {
1653 "applet" => "applet",
1658 "frameset" => "frameset",
1659 "iframe" => "iframe",
1660 "import" => "\?import",
1663 "object" => "object",
1664 "script" => "script",
1668 $ret = base64_encode(serialize($tmp));
1674 * Remove potential xss vectors from strings
1675 * @param string str String to search for XSS attack vectors
1676 * @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images.
1679 function remove_xss($str, $cleanImg=true)
1681 $potentials = clean_xss($str, $cleanImg);
1682 if(is_array($potentials) && !empty($potentials)) {
1683 foreach($potentials as $bad) {
1684 $str = str_replace($bad, "", $str);
1691 * Detects typical XSS attack patterns
1692 * @param string str String to search for XSS attack vectors
1693 * @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images.
1694 * @return array Array of matches, empty on clean string
1696 function clean_xss($str, $cleanImg=true) {
1697 global $sugar_config;
1699 if(empty($sugar_config['email_xss']))
1700 $sugar_config['email_xss'] = getDefaultXssTags();
1702 $arr = unserialize(base64_decode($sugar_config['email_xss']));
1705 foreach($arr as $v) {
1706 if(!empty($regex)) {
1712 $tag_regex = "#<({$regex})[^>]*>?#sim";
1714 // cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.)
1715 $jsEvents = "onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|";
1716 $jsEvents .= "onmouseup|onmouseover|onmousedown|onmouseenter|onmouseleave|onmousemove|onload|onchange|";
1717 $jsEvents .= "onreset|onselect|onsubmit|onkeydown|onkeypress|onkeyup|onabort|onerror|ondragdrop";
1719 $attribute_regex = "#<[^/>][^>]+({$jsEvents})[^=>]*=[^>]*>#sim";
1720 $javascript_regex = '@<[^/>][^>]+(expression\(|j\W*a\W*v\W*a|v\W*b\W*s\W*c\W*r|&#|/\*|\*/)[^>]*>@sim';
1721 $imgsrc_regex = '#<[^>]+src[^=]*=([^>]*?http://[^>]*)>#sim';
1722 $css_url = '#url\(.*\.\w+\)#';
1725 $str = str_replace("\t", "", $str);
1727 $matches = array_merge(
1728 xss_check_pattern($tag_regex, $str),
1729 xss_check_pattern($javascript_regex, $str),
1730 xss_check_pattern($attribute_regex, $str)
1734 $matches = array_merge($matches,
1735 xss_check_pattern($imgsrc_regex, $str)
1739 // cn: bug 13498 - custom white-list of allowed domains that vet remote images
1740 preg_match_all($css_url, $str, $cssUrlMatches, PREG_PATTERN_ORDER);
1742 if(isset($sugar_config['security_trusted_domains']) && !empty($sugar_config['security_trusted_domains']) && is_array($sugar_config['security_trusted_domains'])) {
1743 if(is_array($cssUrlMatches) && count($cssUrlMatches) > 0) {
1744 // normalize whitelist
1745 foreach($sugar_config['security_trusted_domains'] as $k => $v) {
1746 $sugar_config['security_trusted_domains'][$k] = strtolower($v);
1749 foreach($cssUrlMatches[0] as $match) {
1750 $domain = strtolower(substr(strstr($match, "://"), 3));
1751 $baseUrl = substr($domain, 0, strpos($domain, "/"));
1753 if(!in_array($baseUrl, $sugar_config['security_trusted_domains'])) {
1754 $matches[] = $match;
1759 $matches = array_merge($matches, $cssUrlMatches[0]);
1766 * Helper function used by clean_xss() to parse for known-bad vectors
1767 * @param string pattern Regex pattern to use
1768 * @param string str String to parse for badness
1771 function xss_check_pattern($pattern, $str) {
1772 preg_match_all($pattern, $str, $matches, PREG_PATTERN_ORDER);
1776 // Designed to take a string passed in the URL as a parameter and clean all "bad" data from it
1777 // The second argument is a string, "filter," which corresponds to a regular expression
1778 function clean_string($str, $filter = "STANDARD") {
1779 global $sugar_config;
1782 "STANDARD" => '#[^A-Z0-9\-_\.\@]#i',
1783 "STANDARDSPACE" => '#[^A-Z0-9\-_\.\@\ ]#i',
1784 "FILE" => '#[^A-Z0-9\-_\.]#i',
1785 "NUMBER" => '#[^0-9\-]#i',
1786 "SQL_COLUMN_LIST" => '#[^A-Z0-9,_\.]#i',
1787 "PATH_NO_URL" => '#://#i',
1788 "SAFED_GET" => '#[^A-Z0-9\@\=\&\?\.\/\-_~]#i', /* range of allowed characters in a GET string */
1789 "UNIFIED_SEARCH" => "#[\\x00]#", /* cn: bug 3356 & 9236 - MBCS search strings */
1790 "AUTO_INCREMENT" => '#[^0-9\-,\ ]#i',
1791 "ALPHANUM" => '#[^A-Z0-9\-]#i',
1794 if (preg_match($filters[$filter], $str)) {
1795 if (isset($GLOBALS['log']) && is_object($GLOBALS['log'])) {
1796 $GLOBALS['log']->fatal("SECURITY: bad data passed in; string: {$str}");
1798 die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>");
1805 function clean_special_arguments() {
1806 if(isset($_SERVER['PHP_SELF'])) {
1807 if (!empty($_SERVER['PHP_SELF'])) clean_string($_SERVER['PHP_SELF'], 'SAFED_GET');
1809 if (!empty($_REQUEST) && !empty($_REQUEST['login_theme'])) clean_string($_REQUEST['login_theme'], "STANDARD");
1810 if (!empty($_REQUEST) && !empty($_REQUEST['login_module'])) clean_string($_REQUEST['login_module'], "STANDARD");
1811 if (!empty($_REQUEST) && !empty($_REQUEST['login_action'])) clean_string($_REQUEST['login_action'], "STANDARD");
1812 if (!empty($_REQUEST) && !empty($_REQUEST['ck_login_theme_20'])) clean_string($_REQUEST['ck_login_theme_20'], "STANDARD");
1813 if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_theme'])) clean_string($_SESSION['authenticated_user_theme'], "STANDARD");
1814 if (!empty($_REQUEST) && !empty($_REQUEST['module_name'])) clean_string($_REQUEST['module_name'], "STANDARD");
1815 if (!empty($_REQUEST) && !empty($_REQUEST['module'])) clean_string($_REQUEST['module'], "STANDARD");
1816 if (!empty($_POST) && !empty($_POST['parent_type'])) clean_string($_POST['parent_type'], "STANDARD");
1817 if (!empty($_REQUEST) && !empty($_REQUEST['mod_lang'])) clean_string($_REQUEST['mod_lang'], "STANDARD");
1818 if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_language'])) clean_string($_SESSION['authenticated_user_language'], "STANDARD");
1819 if (!empty($_SESSION) && !empty($_SESSION['dyn_layout_file'])) clean_string($_SESSION['dyn_layout_file'], "PATH_NO_URL");
1820 if (!empty($_GET) && !empty($_GET['from'])) clean_string($_GET['from']);
1821 if (!empty($_GET) && !empty($_GET['gmto'])) clean_string($_GET['gmto'], "NUMBER");
1822 if (!empty($_GET) && !empty($_GET['case_number'])) clean_string($_GET['case_number'], "AUTO_INCREMENT");
1823 if (!empty($_GET) && !empty($_GET['bug_number'])) clean_string($_GET['bug_number'], "AUTO_INCREMENT");
1824 if (!empty($_GET) && !empty($_GET['quote_num'])) clean_string($_GET['quote_num'], "AUTO_INCREMENT");
1825 clean_superglobals('stamp', 'ALPHANUM'); // for vcr controls
1826 clean_superglobals('offset', 'ALPHANUM');
1827 clean_superglobals('return_action');
1828 clean_superglobals('return_module');
1833 * cleans the given key in superglobals $_GET, $_POST, $_REQUEST
1835 function clean_superglobals($key, $filter = 'STANDARD') {
1836 if(isset($_GET[$key])) clean_string($_GET[$key], $filter);
1837 if(isset($_POST[$key])) clean_string($_POST[$key], $filter);
1838 if(isset($_REQUEST[$key])) clean_string($_REQUEST[$key], $filter);
1841 function set_superglobals($key, $val){
1843 $_POST[$key] = $val;
1844 $_REQUEST[$key] = $val;
1847 // Works in conjunction with clean_string() to defeat SQL injection, file inclusion attacks, and XSS
1848 function clean_incoming_data() {
1849 global $sugar_config;
1851 if (get_magic_quotes_gpc() == 1) {
1852 $req = array_map("preprocess_param", $_REQUEST);
1853 $post = array_map("preprocess_param", $_POST);
1854 $get = array_map("preprocess_param", $_GET);
1857 $req = array_map("securexss", $_REQUEST);
1858 $post = array_map("securexss", $_POST);
1859 $get = array_map("securexss", $_GET);
1862 // PHP cannot stomp out superglobals reliably
1863 foreach($post as $k => $v) { $_POST[$k] = $v; }
1864 foreach($get as $k => $v) { $_GET[$k] = $v; }
1865 foreach($req as $k => $v) {
1867 //ensure the keys are safe as well
1870 // Any additional variables that need to be cleaned should be added here
1871 if (isset($_REQUEST['login_theme'])) clean_string($_REQUEST['login_theme']);
1872 if (isset($_REQUEST['login_module'])) clean_string($_REQUEST['login_module']);
1873 if (isset($_REQUEST['login_action'])) clean_string($_REQUEST['login_action']);
1874 if (isset($_REQUEST['login_language'])) clean_string($_REQUEST['login_language']);
1875 if (isset($_REQUEST['action'])) clean_string($_REQUEST['action']);
1876 if (isset($_REQUEST['module'])) clean_string($_REQUEST['module']);
1877 if (isset($_REQUEST['record'])) clean_string($_REQUEST['record'], 'STANDARDSPACE');
1878 if (isset($_SESSION['authenticated_user_theme'])) clean_string($_SESSION['authenticated_user_theme']);
1879 if (isset($_SESSION['authenticated_user_language'])) clean_string($_SESSION['authenticated_user_language']);
1880 if (isset($_REQUEST['language'])) clean_string($_REQUEST['language']);
1881 if (isset($sugar_config['default_theme'])) clean_string($sugar_config['default_theme']);
1882 if (isset($_REQUEST['offset'])) clean_string($_REQUEST['offset']);
1883 if (isset($_REQUEST['stamp'])) clean_string($_REQUEST['stamp']);
1885 if(isset($_REQUEST['lvso'])){
1886 set_superglobals('lvso', (strtolower($_REQUEST['lvso']) === 'desc')?'desc':'asc');
1888 // Clean "offset" and "order_by" parameters in URL
1889 foreach ($_REQUEST as $key => $val) {
1890 if (str_end($key, "_offset")) {
1891 clean_string($_REQUEST[$key], "ALPHANUM"); // keep this ALPHANUM for disable_count_query
1892 set_superglobals($key, $_REQUEST[$key]);
1894 elseif (str_end($key, "_ORDER_BY")) {
1895 clean_string($_REQUEST[$key], "SQL_COLUMN_LIST");
1896 set_superglobals($key, $_REQUEST[$key]);
1904 // Returns TRUE if $str begins with $begin
1905 function str_begin($str, $begin) {
1906 return (substr($str, 0, strlen($begin)) == $begin);
1909 // Returns TRUE if $str ends with $end
1910 function str_end($str, $end) {
1911 return (substr($str, strlen($str) - strlen($end)) == $end);
1914 function securexss($value) {
1915 if(is_array($value)){
1917 foreach($value as $key=>$val){
1918 $new[$key] = securexss($val);
1922 static $xss_cleanup= array('"' =>'"', "'" => ''' , '<' =>'<' , '>'=>'>');
1923 $value = preg_replace(array('/javascript:/i', '/\0/'), array('java script:', ''), $value);
1924 $value = preg_replace('/javascript:/i', 'java script:', $value);
1925 return str_replace(array_keys($xss_cleanup), array_values($xss_cleanup), $value);
1928 function securexsskey($value, $die=true){
1929 global $sugar_config;
1931 preg_match("/[\'\"\<\>]/", $value, $matches);
1932 if(!empty($matches)){
1934 die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>");
1936 unset($_REQUEST[$value]);
1937 unset($_POST[$value]);
1938 unset($_GET[$value]);
1943 function preprocess_param($value){
1944 if(is_string($value)){
1945 if(get_magic_quotes_gpc() == 1){
1946 $value = stripslashes($value);
1949 $value = securexss($value);
1958 function set_register_value($category, $name, $value){
1959 return sugar_cache_put("{$category}:{$name}", $value);
1962 function get_register_value($category,$name){
1963 return sugar_cache_retrieve("{$category}:{$name}");
1966 // this function cleans id's when being imported
1967 function convert_id($string)
1969 return preg_replace_callback( '|[^A-Za-z0-9\-]|',
1971 // single quotes are essential here,
1972 // or alternative escape all $ as \$
1974 'return ord($matches[0]);'
1979 * @deprecated use SugarTheme::getImage()
1981 function get_image($image,$other_attributes,$width="",$height="")
1983 return SugarThemeRegistry::current()->getImage(basename($image),
1985 empty($width) ? null : $width,
1986 empty($height) ? null : $height
1990 * @deprecated use SugarTheme::getImageURL()
1992 function getImagePath($image_name)
1994 return SugarThemeRegistry::current()->getImageURL($image_name);
1997 function getWebPath($relative_path){
1998 //if it has a :// then it isn't a relative path
1999 if(substr_count($relative_path, '://') > 0) return $relative_path;
2000 if(defined('TEMPLATE_URL'))$relative_path = SugarTemplateUtilities::getWebPath($relative_path);
2001 return $relative_path;
2004 function getJSPath($relative_path, $additional_attrs=''){
2005 if(defined('TEMPLATE_URL'))$relative_path = SugarTemplateUtilities::getWebPath($relative_path);
2006 if(empty($GLOBALS['sugar_config']['js_custom_version']))$GLOBALS['sugar_config']['js_custom_version'] = 1;
2007 $js_version_key = isset($GLOBALS['js_version_key'])?$GLOBALS['js_version_key']:'';
2008 $path = $relative_path . '?s=' . $js_version_key . '&c=' . $GLOBALS['sugar_config']['js_custom_version'] ;
2009 if ( inDeveloperMode() ) $path .= '&developerMode='.mt_rand();
2010 if(!empty($additonal_attrs)) $path .= '&' . $additional_attrs;
2014 function getSWFPath($relative_path, $additional_params=''){
2015 $path = $relative_path;
2016 if (!empty($additional_params)){
2017 $path .= '?' . $additional_params;
2019 if (defined('TEMPLATE_URL')){
2020 $path = TEMPLATE_URL . '/' . $path;
2029 function getSQLDate($date_str)
2031 if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/',$date_str,$match))
2033 if ( strlen($match[2]) == 1)
2035 $match[2] = "0".$match[2];
2037 if ( strlen($match[1]) == 1)
2039 $match[1] = "0".$match[1];
2041 return "{$match[3]}-{$match[1]}-{$match[2]}";
2043 else if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/',$date_str,$match))
2045 if ( strlen($match[2]) == 1)
2047 $match[2] = "0".$match[2];
2049 if ( strlen($match[1]) == 1)
2051 $match[1] = "0".$match[1];
2053 return "{$match[3]}-{$match[1]}-{$match[2]}";
2061 function clone_history(&$db, $from_id,$to_id, $to_type)
2066 require_once('include/upload_file.php');
2067 $tables = array('calls'=>'Call', 'meetings'=>'Meeting', 'notes'=>'Note', 'tasks'=>'Task');
2069 $location=array('Email'=>"modules/Emails/Email.php",
2070 'Call'=>"modules/Calls/Call.php",
2071 'Meeting'=>"modules/Meetings/Meeting.php",
2072 'Note'=>"modules/Notes/Note.php",
2073 'Tasks'=>"modules/Tasks/Task.php",
2077 foreach($tables as $table=>$bean_class)
2080 if (!class_exists($bean_class))
2082 require_once($location[$bean_class]);
2085 $bProcessingNotes=false;
2086 if ($table=='notes')
2088 $bProcessingNotes=true;
2090 $query = "SELECT id FROM $table WHERE parent_id='$from_id'";
2091 $results = $db->query($query);
2092 while($row = $db->fetchByAssoc($results))
2094 //retrieve existing record.
2095 $bean= new $bean_class();
2096 $bean->retrieve($row['id']);
2097 //process for new instance.
2098 if ($bProcessingNotes)
2100 $old_note_id=$row['id'];
2101 $old_filename=$bean->filename;
2104 $bean->parent_id=$to_id;
2105 $bean->parent_type=$to_type;
2106 if ($to_type=='Contacts' and in_array('contact_id',$bean->column_fields))
2108 $bean->contact_id=$to_id;
2110 $bean->update_date_modified = false;
2111 $bean->update_modified_by = false;
2112 if(isset($bean->date_modified))
2113 $bean->date_modified = $timedate->to_db($bean->date_modified);
2114 if(isset($bean->date_entered))
2115 $bean->date_entered = $timedate->to_db($bean->date_entered);
2117 $new_id=$bean->save();
2119 //duplicate the file now. for notes.
2120 if ($bProcessingNotes && !empty($old_filename))
2122 UploadFile::duplicate_file($old_note_id,$new_id,$old_filename);
2124 //reset the values needed for attachment duplication.
2131 function values_to_keys($array)
2133 $new_array = array();
2134 if(!is_array($array))
2138 foreach($array as $arr){
2139 $new_array[$arr] = $arr;
2144 function clone_relationship(&$db, $tables = array(), $from_column, $from_id, $to_id)
2146 foreach($tables as $table)
2149 if ($table == 'emails_beans') {
2150 $query = "SELECT * FROM $table WHERE $from_column='$from_id' and bean_module='Leads'";
2152 $query = "SELECT * FROM $table WHERE $from_column='$from_id'";
2154 $results = $db->query($query);
2155 while($row = $db->fetchByAssoc($results))
2157 $query = "INSERT INTO $table ";
2160 $row[$from_column] = $to_id;
2161 $row['id'] = create_guid();
2162 if ($table=='emails_beans') {
2163 $row['bean_module'] =='Contacts';
2166 foreach($row as $name=>$value)
2172 $values .= "'$value'";
2175 $names .= ', '. $name;
2176 $values .= ", '$value'";
2179 $query .= "($names) VALUES ($values)";
2185 function get_unlinked_email_query($type, $bean) {
2186 global $current_user;
2188 $return_array['select']='SELECT emails.id ';
2189 $return_array['from']='FROM emails ';
2190 $return_array['where']="";
2191 $return_array['join'] = " JOIN (select distinct email_id from emails_email_addr_rel eear
2193 join email_addr_bean_rel eabr on eabr.bean_id ='$bean->id' and eabr.bean_module = '$bean->module_dir' and
2194 eabr.email_address_id = eear.email_address_id and eabr.deleted=0
2195 where eear.deleted=0 and eear.email_id not in
2196 (select eb.email_id from emails_beans eb where eb.bean_module ='$bean->module_dir' and eb.bean_id = '$bean->id')
2197 ) derivedemails on derivedemails.email_id = emails.id";
2198 $return_array['join_tables'][0] = '';
2200 if (isset($type) and isset($type['return_as_array']) and $type['return_as_array']==true) {
2201 return $return_array;
2204 return $return_array['select'] . $return_array['from'] . $return_array['where'];
2208 * Check to see if the number is empty or non-zero
2212 function number_empty($value)
2214 return empty($value) && $value != '0';
2217 function get_bean_select_array($add_blank=true, $bean_name, $display_columns, $where='', $order_by='', $blank_is_none=false)
2220 require_once($beanFiles[$bean_name]);
2221 $focus = new $bean_name();
2222 $user_array = array();
2223 $user_array = get_register_value('select_array',$bean_name. $display_columns. $where . $order_by);
2227 $db = DBManagerFactory::getInstance();
2228 $temp_result = Array();
2229 $query = "SELECT id, {$display_columns} as display from {$focus->table_name} ";
2233 $query .= $where." AND ";
2236 $query .= " deleted=0";
2238 if ( $order_by != '')
2240 $query .= ' order by '.$order_by;
2243 $GLOBALS['log']->debug("get_user_array query: $query");
2244 $result = $db->query($query, true, "Error filling in user array: ");
2246 if ($add_blank==true){
2247 // Add in a blank row
2248 if($blank_is_none == true) { // set 'blank row' to "--None--"
2249 global $app_strings;
2250 $temp_result[''] = $app_strings['LBL_NONE'];
2252 $temp_result[''] = '';
2256 // Get the id and the name.
2257 while($row = $db->fetchByAssoc($result))
2259 $temp_result[$row['id']] = $row['display'];
2262 $user_array = $temp_result;
2263 set_register_value('select_array',$bean_name. $display_columns. $where . $order_by,$temp_result);
2272 * @param unknown_type $listArray
2274 // function parse_list_modules
2275 // searches a list for items in a user's allowed tabs and returns an array that removes unallowed tabs from list
2276 function parse_list_modules(&$listArray)
2278 global $modListHeader;
2279 $returnArray = array();
2281 foreach($listArray as $optionName => $optionVal)
2283 if(array_key_exists($optionName, $modListHeader))
2285 $returnArray[$optionName] = $optionVal;
2288 // special case for projects
2289 if(array_key_exists('Project', $modListHeader))
2291 $returnArray['ProjectTask'] = $listArray['ProjectTask'];
2294 $acldenied = ACLController::disabledModuleList($listArray,false);
2295 foreach($acldenied as $denied){
2296 unset($returnArray[$denied]);
2298 asort($returnArray);
2300 return $returnArray;
2303 function display_notice($msg = false){
2304 global $error_notice;
2305 //no error notice - lets just display the error to the user
2306 if(!isset($error_notice)){
2307 echo '<br>'.$msg . '<br>';
2309 $error_notice .= $msg . '<br>';
2313 /* checks if it is a number that atleast has the plus at the beggining
2315 function skype_formatted($number){
2316 //kbrill - BUG #15375
2317 if(isset($_REQUEST['action']) && $_REQUEST['action']=="Popup") {
2320 return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 3) == '011';
2322 // return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 2) == '011';
2325 function format_skype($number) {
2326 return preg_replace('/[^\+0-9]/','',$number);
2329 function insert_charset_header() {
2330 header('Content-Type: text/html; charset=UTF-8');
2333 function getCurrentURL()
2336 if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')
2341 $href.= "//".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
2345 function javascript_escape($str) {
2348 for($i = 0; $i < strlen($str); $i++) {
2350 if(ord(substr($str, $i, 1))==10){
2352 }elseif(ord(substr($str, $i, 1))==13){
2356 $new_str .= $str{$i};
2360 $new_str = str_replace("'", "\\'", $new_str);
2365 function js_escape($str, $keep=true){
2366 $str = html_entity_decode(str_replace("\\", "", $str), ENT_QUOTES);
2369 $str = javascript_escape($str);
2372 $str = str_replace("'", " ", $str);
2373 $str = str_replace('"', " ", $str);
2378 //end function js_escape
2381 function br2nl($str) {
2382 $regex = "#<[^>]+br.+?>#i";
2383 preg_match_all($regex, $str, $matches);
2385 foreach($matches[0] as $match) {
2386 $str = str_replace($match, "<br>", $str);
2389 $brs = array('<br>','<br/>', '<br />');
2390 $str = str_replace("\r\n", "\n", $str); // make from windows-returns, *nix-returns
2391 $str = str_replace("\n\r", "\n", $str); // make from windows-returns, *nix-returns
2392 $str = str_replace("\r", "\n", $str); // make from windows-returns, *nix-returns
2393 $str = str_ireplace($brs, "\n", $str); // to retrieve it
2399 * Private helper function for displaying the contents of a given variable.
2400 * This function is only intended to be used for SugarCRM internal development.
2401 * The ppd stands for Pre Print Die.
2403 function _ppd($mixed)
2409 * Private helper function for displaying the contents of a given variable in
2410 * the Logger. This function is only intended to be used for SugarCRM internal
2411 * development. The pp stands for Pre Print.
2412 * @param $mixed var to print_r()
2413 * @param $die boolean end script flow
2414 * @param $displayStackTrace also show stack trace
2416 function _ppl($mixed, $die=false, $displayStackTrace=false, $loglevel="fatal") {
2420 * private helper function to quickly show the major, direct, field attributes of a given bean.
2421 * The ppf stands for Pre[formatted] Print Focus [object]
2422 * @param object bean The focus bean
2424 function _ppf($bean, $die=false) {
2430 * Private helper function for displaying the contents of a given variable.
2431 * This function is only intended to be used for SugarCRM internal development.
2432 * The pp stands for Pre Print.
2434 function _pp($mixed)
2439 * Private helper function for displaying the contents of a given variable.
2440 * This function is only intended to be used for SugarCRM internal development.
2441 * The pp stands for Pre Print.
2443 function _pstack_trace($mixed=NULL)
2448 * Private helper function for displaying the contents of a given variable.
2449 * This function is only intended to be used for SugarCRM internal development.
2450 * The pp stands for Pre Print Trace.
2452 function _ppt($mixed, $textOnly=false)
2457 * Private helper function for displaying the contents of a given variable.
2458 * This function is only intended to be used for SugarCRM internal development.
2459 * The pp stands for Pre Print Trace Die.
2461 function _pptd($mixed)
2466 * Private helper function for decoding javascript UTF8
2467 * This function is only intended to be used for SugarCRM internal development.
2469 function decodeJavascriptUTF8($str) {
2473 * Will check if a given PHP version string is supported (tested on this ver),
2474 * unsupported (results unknown), or invalid (something will break on this
2475 * ver). Do not pass in any pararameter to default to a check against the
2476 * current environment's PHP version.
2478 * @return 1 implies supported, 0 implies unsupported, -1 implies invalid
2480 function check_php_version($sys_php_version = '') {
2481 $sys_php_version = empty($sys_php_version) ? constant('PHP_VERSION') : $sys_php_version;
2482 // versions below $min_considered_php_version considered invalid by default,
2483 // versions equal to or above this ver will be considered depending
2484 // on the rules that follow
2485 $min_considered_php_version = '5.2.1';
2487 // only the supported versions,
2488 // should be mutually exclusive with $invalid_php_versions
2489 $supported_php_versions = array (
2490 '5.2.1', '5.2.2', '5.2.3', '5.2.4', '5.2.5', '5.2.6', '5.2.8', '5.3.0'
2492 //Find out what Database the system is using.
2493 global $sugar_config;
2495 if (isset($_REQUEST['setup_db_type'])) {
2496 $dbType = $_REQUEST['setup_db_type'];
2497 } else if (isset ($sugar_config['dbconfig']) && isset ($sugar_config['dbconfig']['db_type'])) {
2498 $dbType = $sugar_config['dbconfig']['db_type'];
2501 // invalid versions above the $min_considered_php_version,
2502 // should be mutually exclusive with $supported_php_versions
2504 // SugarCRM prohibits install on PHP 5.2.7 on all platforms
2505 $invalid_php_versions = array('5.2.7');
2507 // default unsupported
2510 // versions below $min_considered_php_version are invalid
2511 if(1 == version_compare($sys_php_version, $min_considered_php_version, '<')) {
2515 // supported version check overrides default unsupported
2516 foreach($supported_php_versions as $ver) {
2517 if(1 == version_compare($sys_php_version, $ver, 'eq') || strpos($sys_php_version,$ver) !== false) {
2523 // invalid version check overrides default unsupported
2524 foreach($invalid_php_versions as $ver) {
2525 if(1 == version_compare($sys_php_version, $ver, 'eq') && strpos($sys_php_version,$ver) !== false) {
2531 //allow a redhat distro to install, regardless of version. We are assuming the redhat naming convention is followed
2532 //and the php version contains 'rh' characters
2533 if(strpos($sys_php_version, 'rh') !== false) {
2541 * Will check if a given IIS version string is supported (tested on this ver),
2542 * unsupported (results unknown), or invalid (something will break on this
2545 * @return 1 implies supported, 0 implies unsupported, -1 implies invalid
2547 function check_iis_version($sys_iis_version = '') {
2549 $server_software = $_SERVER["SERVER_SOFTWARE"];
2551 if(strpos($server_software,'Microsoft-IIS') !== false && preg_match_all("/^.*\/(\d+\.?\d*)$/", $server_software, $out))
2552 $iis_version = $out[1][0];
2554 $sys_iis_version = empty($sys_iis_version) ? $iis_version : $sys_iis_version;
2556 // versions below $min_considered_iis_version considered invalid by default,
2557 // versions equal to or above this ver will be considered depending
2558 // on the rules that follow
2559 $min_considered_iis_version = '6.0';
2561 // only the supported versions,
2562 // should be mutually exclusive with $invalid_iis_versions
2563 $supported_iis_versions = array ('6.0', '7.0',);
2564 $unsupported_iis_versions = array();
2565 $invalid_iis_versions = array('5.0',);
2567 // default unsupported
2570 // versions below $min_considered_iis_version are invalid
2571 if(1 == version_compare($sys_iis_version, $min_considered_iis_version, '<')) {
2575 // supported version check overrides default unsupported
2576 foreach($supported_iis_versions as $ver) {
2577 if(1 == version_compare($sys_iis_version, $ver, 'eq') || strpos($sys_iis_version,$ver) !== false) {
2583 // unsupported version check overrides default unsupported
2584 foreach($unsupported_iis_versions as $ver) {
2585 if(1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version,$ver) !== false) {
2591 // invalid version check overrides default unsupported
2592 foreach($invalid_iis_versions as $ver) {
2593 if(1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version,$ver) !== false) {
2602 function pre_login_check(){
2603 global $action, $login_error;
2604 if(!empty($action)&& $action == 'Login'){
2606 if(!empty($login_error)){
2607 $login_error = htmlentities($login_error);
2608 $login_error = str_replace(array("<pre>","</pre>","\r\n", "\n"), "<br>", $login_error);
2609 $_SESSION['login_error'] = $login_error;
2611 function set_focus() {}
2612 if(document.getElementById("post_error")) {
2613 document.getElementById("post_error").innerHTML="'. $login_error. '";
2614 document.getElementById("cant_login").value=1;
2615 document.getElementById("login_button").disabled = true;
2616 document.getElementById("user_name").disabled = true;
2617 //document.getElementById("user_password").disabled = true;
2626 function sugar_cleanup($exit = false) {
2627 static $called = false;
2630 set_include_path(realpath(dirname(__FILE__) . '/..') . PATH_SEPARATOR . get_include_path());
2631 chdir(realpath(dirname(__FILE__) . '/..'));
2632 global $sugar_config;
2633 require_once('include/utils/LogicHook.php');
2634 LogicHook::initialize();
2635 $GLOBALS['logic_hook']->call_custom_logic('', 'server_round_trip');
2637 //added this check to avoid errors during install.
2638 if (empty($sugar_config['dbconfig'])) {
2639 if ($exit) exit; else return;
2642 if (!class_exists('Tracker', true)) {
2643 require_once 'modules/Trackers/Tracker.php';
2646 // Now write the cached tracker_queries
2647 if(!empty($GLOBALS['savePreferencesToDB']) && $GLOBALS['savePreferencesToDB']) {
2648 if ( isset($GLOBALS['current_user']) && $GLOBALS['current_user'] instanceOf User )
2649 $GLOBALS['current_user']->savePreferencesToDB();
2652 //check to see if this is not an ajax call AND the user preference error flag is set
2654 (isset($_SESSION['USER_PREFRENCE_ERRORS']) && $_SESSION['USER_PREFRENCE_ERRORS'])
2655 && ($_REQUEST['action']!='modulelistmenu' && $_REQUEST['action']!='DynamicAction')
2656 && (empty($_REQUEST['to_pdf']) || !$_REQUEST['to_pdf'] )
2657 && (empty($_REQUEST['sugar_body_only']) || !$_REQUEST['sugar_body_only'] )
2660 global $app_strings;
2661 //this is not an ajax call and the user preference error flag is set, so reset the flag and print js to flash message
2662 $err_mess = $app_strings['ERROR_USER_PREFS'];
2663 $_SESSION['USER_PREFRENCE_ERRORS'] = false;
2666 ajaxStatus.flashStatus('$err_mess',7000);
2672 if(class_exists('DBManagerFactory')) {
2673 $db = DBManagerFactory::getInstance();
2681 register_shutdown_function('sugar_cleanup');
2685 check_logic_hook - checks to see if your custom logic is in the logic file
2686 if not, it will add it. If the file isn't built yet, it will create the file
2689 function check_logic_hook_file($module_name, $event, $action_array){
2690 require_once('include/utils/logic_utils.php');
2693 if(file_exists("custom/modules/$module_name/logic_hooks.php")){
2695 $hook_array = get_hook_array($module_name);
2697 if(check_existing_element($hook_array, $event, $action_array)==true){
2698 //the hook at hand is present, so do nothing
2702 $logic_count = count($hook_array[$event]);
2703 if($action_array[0]==""){
2704 $action_array[0] = $logic_count + 1;
2706 $hook_array[$event][] = $action_array;
2709 //end if the file exists already
2712 if($action_array[0]==""){
2713 $action_array[0] = 1;
2715 $hook_array = array();
2716 $hook_array[$event][] = $action_array;
2717 //end if else file exists already
2719 if($add_logic == true){
2721 //reorder array by element[0]
2722 //$hook_array = reorder_array($hook_array, $event);
2723 //!!!Finish this above TODO
2725 $new_contents = replace_or_add_logic_type($hook_array);
2726 write_logic_file($module_name, $new_contents);
2728 //end if add_element is true
2731 //end function check_logic_hook_file
2734 function remove_logic_hook($module_name, $event, $action_array) {
2735 require_once('include/utils/logic_utils.php');
2738 if(file_exists("custom/modules/".$module_name."/logic_hooks.php")){
2739 // The file exists, let's make sure the hook is there
2740 $hook_array = get_hook_array($module_name);
2742 if(check_existing_element($hook_array, $event, $action_array)==true){
2743 // The hook is there, time to take it out.
2745 foreach ( $hook_array[$event] as $i => $hook ) {
2746 // We don't do a full comparison below just in case the filename changes
2747 if ( $hook[0] == $action_array[0]
2748 && $hook[1] == $action_array[1]
2749 && $hook[3] == $action_array[3]
2750 && $hook[4] == $action_array[4] ) {
2751 unset($hook_array[$event][$i]);
2755 $new_contents = replace_or_add_logic_type($hook_array);
2756 write_logic_file($module_name, $new_contents);
2762 function display_stack_trace($textOnly=false){
2764 $stack = debug_backtrace();
2766 echo "\n\n display_stack_trace caller, file: " . $stack[0]['file']. ' line#: ' .$stack[0]['line'];
2774 foreach($stack as $item) {
2780 if(isset($item['file']))
2781 $file = $item['file'];
2782 if(isset($item['class']))
2783 $class = $item['class'];
2784 if(isset($item['line']))
2785 $line = $item['line'];
2786 if(isset($item['function']))
2787 $function = $item['function'];
2791 $out .= '<font color="black"><b>';
2797 $out .= '</b></font><font color="blue">';
2800 $out .= "[L:{$line}]";
2803 $out .= '</font><font color="red">';
2806 $out .= "({$class}:{$function})";
2809 $out .= '</font><br>';
2821 function StackTraceErrorHandler($errno, $errstr, $errfile,$errline, $errcontext) {
2822 $error_msg = " $errstr occured in <b>$errfile</b> on line $errline [" . date("Y-m-d H:i:s") . ']';
2823 $halt_script = true;
2825 case 2048: return; //depricated we have lots of these ignore them
2828 if ( error_reporting() & E_NOTICE ) {
2829 $halt_script = false;
2835 case E_USER_WARNING:
2836 case E_COMPILE_WARNING:
2837 case E_CORE_WARNING:
2840 $halt_script = false;
2845 case E_COMPILE_ERROR:
2849 $type = "Fatal Error";
2854 $type = "Parse Error";
2858 //don't know what it is might not be so bad
2859 $halt_script = false;
2860 $type = "Unknown Error ($errno)";
2863 $error_msg = '<b>'.$type.'</b>:' . $error_msg;
2865 display_stack_trace();
2875 if(isset($sugar_config['stack_trace_errors']) && $sugar_config['stack_trace_errors']){
2877 set_error_handler('StackTraceErrorHandler');
2879 function get_sub_cookies($name){
2881 if(isset($_COOKIE[$name])){
2882 $subs = explode('#', $_COOKIE[$name]);
2883 foreach($subs as $cookie){
2884 if(!empty($cookie)){
2885 $cookie = explode('=', $cookie);
2887 $cookies[$cookie[0]] = $cookie[1];
2896 function mark_delete_components($sub_object_array, $run_second_level=false, $sub_sub_array=""){
2898 if(!empty($sub_object_array)){
2900 foreach($sub_object_array as $sub_object){
2902 //run_second level is set to true if you need to remove sub-sub components
2903 if($run_second_level==true){
2905 mark_delete_components($sub_object->get_linked_beans($sub_sub_array['rel_field'],$sub_sub_array['rel_module']));
2907 //end if run_second_level is true
2909 $sub_object->mark_deleted($sub_object->id);
2910 //end foreach sub component
2912 //end if this is not empty
2915 //end function mark_delete_components
2919 * For translating the php.ini memory values into bytes. e.g. input value of '8M' will return 8388608.
2921 function return_bytes($val)
2924 $last = strtolower($val{strlen($val)-1});
2928 // The 'G' modifier is available since PHP 5.1.0
2941 * Adds the href HTML tags around any URL in the $string
2943 function url2html($string) {
2945 $return_string = preg_replace('/(\w+:\/\/)(\S+)/', ' <a href="\\1\\2" target="_new" style="font-weight: normal;">\\1\\2</a>', $string);
2946 return $return_string;
2948 // End customization by Julian
2951 * tries to determine whether the Host machine is a Windows machine
2953 function is_windows() {
2954 static $is_windows = null;
2955 if (!isset($is_windows)) {
2956 $is_windows = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN';
2962 * equivalent for windows filesystem for PHP's is_writable()
2963 * @param string file Full path to the file/dir
2964 * @return bool true if writable
2966 function is_writable_windows($file) {
2967 if($file{strlen($file)-1}=='/') {
2968 return is_writable_windows($file.uniqid(mt_rand()).'.tmp');
2971 // the assumption here is that Windows has an inherited permissions scheme
2972 // any file that is a descendant of an unwritable directory will inherit
2973 // that property and will trigger a failure below.
2978 $file = str_replace("/", '\\', $file);
2980 if(file_exists($file)) {
2981 if (!($f = @sugar_fopen($file, 'r+')))
2987 if(!($f = @sugar_fopen($file, 'w')))
2996 * best guesses Timezone based on webserver's TZ settings
2998 function lookupTimezone($userOffset = 0)
3000 return TimeDate::guessTimezone($userOffset);
3003 function convert_module_to_singular($module_array){
3006 foreach($module_array as $key => $value){
3007 if(!empty($beanList[$value])) $module_array[$key] = $beanList[$value];
3009 if($value=="Cases") {
3010 $module_array[$key] = "Case";
3012 if($key=="projecttask"){
3013 $module_array['ProjectTask'] = "Project Task";
3014 unset($module_array[$key]);
3018 return $module_array;
3020 //end function convert_module_to_singular
3024 * Given the bean_name which may be plural or singular return the singular
3025 * bean_name. This is important when you need to include files.
3027 function get_singular_bean_name($bean_name){
3028 global $beanFiles, $beanList;
3029 if(array_key_exists($bean_name, $beanList)){
3030 return $beanList[$bean_name];
3037 function get_label($label_tag, $temp_module_strings){
3038 global $app_strings;
3039 if(!empty($temp_module_strings[$label_tag])){
3041 $label_name = $temp_module_strings[$label_tag];
3043 if(!empty($app_strings[$label_tag])){
3044 $label_name = $app_strings[$label_tag];
3046 $label_name = $label_tag;
3051 //end function get_label
3055 function search_filter_rel_info(& $focus, $tar_rel_module, $relationship_name){
3057 $rel_list = array();
3059 foreach($focus->relationship_fields as $rel_key => $rel_value){
3060 if($rel_value == $relationship_name){
3061 $temp_bean = get_module_info($tar_rel_module);
3062 // echo $focus->$rel_key;
3063 $temp_bean->retrieve($focus->$rel_key);
3064 if($temp_bean->id!=""){
3066 $rel_list[] = $temp_bean;
3072 foreach($focus->field_defs as $field_name => $field_def){
3073 //Check if the relationship_name matches a "relate" field
3074 if(!empty($field_def['type']) && $field_def['type'] == 'relate'
3075 && !empty($field_def['id_name']) && !empty($focus->field_defs[$field_def['id_name']])
3076 && !empty($focus->field_defs[$field_def['id_name']]['relationship'])
3077 && $focus->field_defs[$field_def['id_name']]['relationship'] == $relationship_name)
3079 $temp_bean = get_module_info($tar_rel_module);
3080 // echo $focus->$field_def['id_name'];
3081 $temp_bean->retrieve($focus->$field_def['id_name']);
3082 if($temp_bean->id!=""){
3084 $rel_list[] = $temp_bean;
3087 //Check if the relationship_name matches a "link" in a relate field
3088 } else if(!empty($rel_value['link']) && !empty($rel_value['id_name']) && $rel_value['link'] == $relationship_name){
3089 $temp_bean = get_module_info($tar_rel_module);
3090 // echo $focus->$rel_value['id_name'];
3091 $temp_bean->retrieve($focus->$rel_value['id_name']);
3092 if($temp_bean->id!=""){
3094 $rel_list[] = $temp_bean;
3100 // special case for unlisted parent-type relationships
3101 if($focus->parent_type == $tar_rel_module && !empty($focus->parent_id)) {
3102 $temp_bean = get_module_info($tar_rel_module);
3103 $temp_bean->retrieve($focus->parent_id);
3104 if($temp_bean->id!=""){
3105 $rel_list[] = $temp_bean;
3112 //end function search_filter_rel_info
3115 function get_module_info($module_name){
3119 //Get dictionary and focus data for module
3120 $vardef_name = $beanList[$module_name];
3122 if($vardef_name=="aCase"){
3123 $class_name = "Case";
3125 $class_name = $vardef_name;
3128 if(!file_exists('modules/'. $module_name . '/'.$class_name.'.php')){
3132 include_once('modules/'. $module_name . '/'.$class_name.'.php');
3134 $module_bean = new $vardef_name();
3135 return $module_bean;
3136 //end function get_module_table
3140 * In order to have one place to obtain the proper object name. aCase for example causes issues throughout the application.
3142 * @param string $moduleName
3144 function get_valid_bean_name($module_name){
3147 $vardef_name = $beanList[$module_name];
3148 if($vardef_name=="aCase"){
3149 $bean_name = "Case";
3151 $bean_name = $vardef_name;
3158 function checkAuthUserStatus(){
3165 * This function returns an array of phpinfo() results that can be parsed and
3166 * used to figure out what version we run, what modules are compiled in, etc.
3167 * @param $level int info level constant (1,2,4,8...64);
3168 * @return $returnInfo array array of info about the PHP environment
3169 * @author original by "code at adspeed dot com" Fron php.net
3170 * @author customized for Sugar by Chris N.
3172 function getPhpInfo($level=-1) {
3173 /** Name (constant) Value Description
3174 INFO_GENERAL 1 The configuration line, php.ini location, build date, Web Server, System and more.
3175 INFO_CREDITS 2 PHP Credits. See also phpcredits().
3176 INFO_CONFIGURATION 4 Current Local and Master values for PHP directives. See also ini_get().
3177 INFO_MODULES 8 Loaded modules and their respective settings. See also get_loaded_extensions().
3178 INFO_ENVIRONMENT 16 Environment Variable information that's also available in $_ENV.
3179 INFO_VARIABLES 32 Shows all predefined variables from EGPCS (Environment, GET, POST, Cookie, Server).
3180 INFO_LICENSE 64 PHP License information. See also the license FAQ.
3181 INFO_ALL -1 Shows all of the above. This is the default value.
3185 $phpinfo = ob_get_contents();
3188 $phpinfo = strip_tags($phpinfo,'<h1><h2><th><td>');
3189 $phpinfo = preg_replace('/<th[^>]*>([^<]+)<\/th>/',"<info>\\1</info>",$phpinfo);
3190 $phpinfo = preg_replace('/<td[^>]*>([^<]+)<\/td>/',"<info>\\1</info>",$phpinfo);
3191 $parsedInfo = preg_split('/(<h.?>[^<]+<\/h.>)/', $phpinfo, -1, PREG_SPLIT_DELIM_CAPTURE);
3194 $returnInfo = array();
3196 if(preg_match('/<h1 class\=\"p\">PHP Version ([^<]+)<\/h1>/', $phpinfo, $version)) {
3197 $returnInfo['PHP Version'] = $version[1];
3201 for ($i=1; $i<count($parsedInfo); $i++) {
3202 if (preg_match('/<h.>([^<]+)<\/h.>/', $parsedInfo[$i], $match)) {
3203 $vName = trim($match[1]);
3204 $parsedInfo2 = explode("\n",$parsedInfo[$i+1]);
3206 foreach ($parsedInfo2 AS $vOne) {
3207 $vPat = '<info>([^<]+)<\/info>';
3208 $vPat3 = "/$vPat\s*$vPat\s*$vPat/";
3209 $vPat2 = "/$vPat\s*$vPat/";
3211 if (preg_match($vPat3,$vOne,$match)) { // 3cols
3212 $returnInfo[$vName][trim($match[1])] = array(trim($match[2]),trim($match[3]));
3213 } elseif (preg_match($vPat2,$vOne,$match)) { // 2cols
3214 $returnInfo[$vName][trim($match[1])] = trim($match[2]);
3226 * This function will take a string that has tokens like {0}, {1} and will replace
3227 * those tokens with the args provided
3228 * @param $format string to format
3229 * @param $args args to replace
3230 * @return $result a formatted string
3232 function string_format($format, $args){
3234 for($i = 0; $i < count($args); $i++){
3235 $result = str_replace('{'.$i.'}', $args[$i], $result);
3241 * Generate a string for displaying a unique identifier that is composed
3242 * of a system_id and number. This is use to allow us to generate quote
3243 * numbers using a DB auto-increment key from offline clients and still
3244 * have the number be unique (since it is modified by the system_id.
3246 * @param $num of bean
3247 * @param $system_id from system
3248 * @return $result a formatted string
3250 function format_number_display($num, $system_id){
3251 global $sugar_config;
3252 if(isset($num) && !empty($num)){
3253 $num=unformat_number($num);
3254 if(isset($system_id) && $system_id == 1){
3255 return sprintf("%d", $num);
3258 return sprintf("%d-%d", $num, $system_id);
3262 function checkLoginUserStatus(){
3266 * This function will take a number and system_id and format
3267 * @param $url URL containing host to append port
3268 * @param $port the port number - if '' is passed, no change to url
3269 * @return $resulturl the new URL with the port appended to the host
3271 function appendPortToHost($url, $port)
3275 // if no port, don't change the url
3278 $split = explode("/", $url);
3279 //check if it starts with http, in case they didn't include that in url
3280 if(str_begin($url, 'http'))
3282 //third index ($split[2]) will be the host
3283 $split[2] .= ":".$port;
3285 else // otherwise assumed to start with host name
3287 //first index ($split[0]) will be the host
3288 $split[0] .= ":".$port;
3291 $resulturl = implode("/", $split);
3298 * Singleton to return JSON object
3299 * @return JSON object
3301 function getJSONobj() {
3302 static $json = null;
3304 require_once('include/JSON.php');
3305 $json = new JSON(JSON_LOOSE_TYPE);
3310 require_once('include/utils/db_utils.php');
3311 //check to see if custom utils exists
3312 if(file_exists('custom/include/custom_utils.php')){
3313 include_once('custom/include/custom_utils.php');
3318 * Set default php.ini settings for entry points
3320 function setPhpIniSettings() {
3322 // Bug 37579 - Comment out force enabling zlib.output_compression, since it can cause problems on certain hosts
3324 if(function_exists('gzclose') && headers_sent() == false) {
3325 ini_set('zlib.output_compression', 1);
3329 //nsingh: breaks zip/unzip functionality. Commenting out 4/23/08
3331 /*if(function_exists('mb_strlen')) {
3332 ini_set('mbstring.func_overload', 7);
3333 ini_set('mbstring.internal_encoding', 'UTF-8');
3337 // http://us3.php.net/manual/en/ref.pcre.php#ini.pcre.backtrack-limit
3338 // starting with 5.2.0, backtrack_limit breaks JSON decoding
3339 $backtrack_limit = ini_get('pcre.backtrack_limit');
3340 if(!empty($backtrack_limit)) {
3341 ini_set('pcre.backtrack_limit', '-1');
3345 if(ini_get("mssql.charset")) {
3346 ini_set('mssql.charset', "UTF-8");
3351 * like array_merge() but will handle array elements that are themselves arrays;
3352 * PHP's version just overwrites the element with the new one.
3354 * @internal Note that this function deviates from the internal array_merge()
3355 * functions in that it does does not treat numeric keys differently
3356 * than string keys. Additionally, it deviates from
3357 * array_merge_recursive() by not creating an array when like values
3360 * @param array gimp the array whose values will be overloaded
3361 * @param array dom the array whose values will pwn the gimp's
3362 * @return array beaten gimp
3364 function sugarArrayMerge($gimp, $dom) {
3365 if(is_array($gimp) && is_array($dom)) {
3366 foreach($dom as $domKey => $domVal) {
3367 if(array_key_exists($domKey, $gimp)) {
3368 if(is_array($domVal)) {
3370 foreach ( $domVal as $domArrKey => $domArrVal )
3371 $tempArr[$domArrKey] = $domArrVal;
3372 foreach ( $gimp[$domKey] as $gimpArrKey => $gimpArrVal )
3373 if ( !array_key_exists($gimpArrKey, $tempArr) )
3374 $tempArr[$gimpArrKey] = $gimpArrVal;
3375 $gimp[$domKey] = $tempArr;
3377 $gimp[$domKey] = $domVal;
3380 $gimp[$domKey] = $domVal;
3384 // if the passed value for gimp isn't an array, then return the $dom
3385 elseif(is_array($dom))
3392 * Similiar to sugarArrayMerge except arrays of N depth are merged.
3394 * @param array gimp the array whose values will be overloaded
3395 * @param array dom the array whose values will pwn the gimp's
3396 * @return array beaten gimp
3398 function sugarArrayMergeRecursive($gimp, $dom) {
3399 if(is_array($gimp) && is_array($dom)) {
3400 foreach($dom as $domKey => $domVal) {
3401 if(array_key_exists($domKey, $gimp)) {
3402 if(is_array($domVal) && is_array($gimp[$domKey])) {
3403 $gimp[$domKey] = sugarArrayMergeRecursive($gimp[$domKey], $domVal);
3405 $gimp[$domKey] = $domVal;
3408 $gimp[$domKey] = $domVal;
3412 // if the passed value for gimp isn't an array, then return the $dom
3413 elseif(is_array($dom))
3420 * finds the correctly working versions of PHP-JSON
3421 * @return bool True if NOT found or WRONG version
3423 function returnPhpJsonStatus() {
3424 if(function_exists('json_encode')) {
3425 $phpInfo = getPhpInfo(8);
3426 return version_compare($phpInfo['json']['json version'], '1.1.1', '<');
3428 return true; // not found
3433 * getTrackerSubstring
3435 * Returns a [number]-char or less string for the Tracker to display in the header
3436 * based on the tracker_max_display_length setting in config.php. If not set,
3437 * or invalid length, then defaults to 15 for COM editions, 30 for others.
3439 * @param string name field for a given Object
3440 * @return string [number]-char formatted string if length of string exceeds the max allowed
3442 function getTrackerSubstring($name) {
3443 static $max_tracker_item_length;
3446 $name = html_entity_decode($name, ENT_QUOTES, 'UTF-8');
3447 $strlen = function_exists('mb_strlen') ? mb_strlen($name) : strlen($name);
3449 global $sugar_config;
3451 if(!isset($max_tracker_item_length)) {
3452 if(isset($sugar_config['tracker_max_display_length'])) {
3453 $max_tracker_item_length = (is_int($sugar_config['tracker_max_display_length']) && $sugar_config['tracker_max_display_length'] > 0 && $sugar_config['tracker_max_display_length'] < 50) ? $sugar_config['tracker_max_display_length'] : 15;
3455 $max_tracker_item_length = 15;
3459 if($strlen > $max_tracker_item_length) {
3460 $chopped = function_exists('mb_substr') ? mb_substr($name, 0, $max_tracker_item_length, "UTF-8") : substr($name, 0, $max_tracker_item_length, "UTF-8");
3467 function generate_search_where ($field_list=array(),$values=array(),&$bean,$add_custom_fields=false,$module='') {
3468 $where_clauses= array();
3470 $table_name=$bean->object_name;
3471 foreach ($field_list[$module] as $field=>$parms) {
3472 if(isset($values[$field]) && $values[$field] != "") {
3474 if (!empty($parms['operator'])) {
3475 $operator=$parms['operator'];
3477 if (is_array($values[$field])) {
3480 foreach ($values[$field] as $key => $val) {
3481 if ($val != ' ' and $val != '') {
3482 if (!empty($field_value)) {
3485 $field_value .= "'".$GLOBALS['db']->quote($val)."'";
3489 $field_value=$GLOBALS['db']->quote($values[$field]);
3491 //set db_fields array.
3492 if (!isset($parms['db_field']) ) {
3493 $parms['db_field'] = array($field);
3495 if (isset($parms['my_items']) and $parms['my_items'] == true) {
3496 global $current_user;
3497 $field_value = $GLOBALS['db']->quote($current_user->id);
3503 if ($field_value != '') {
3505 foreach ($parms['db_field'] as $db_field) {
3506 if (strstr($db_field,'.')===false) {
3507 $db_field=$bean->table_name.".".$db_field;
3509 if ($GLOBALS['db']->dbType=='oci8' && isset($parms['query_type']) && $parms['query_type']=='case_insensitive') {
3510 $db_field='upper('.$db_field.")";
3511 $field_value=strtoupper($field_value);
3515 if (!empty($where)) {
3518 switch (strtolower($operator)) {
3520 $where .= $db_field . " like '".$field_value.$like_char."'";
3523 $where .= $db_field . " in (".$field_value.')';
3526 $where .= $db_field . " = '".$field_value ."'";
3531 if (!empty($where)) {
3533 array_push($where_clauses, '( '.$where.' )');
3535 array_push($where_clauses, $where);
3540 if ($add_custom_fields) {
3541 require_once('modules/DynamicFields/DynamicField.php');
3542 $bean->setupCustomFields($module);
3543 $bean->custom_fields->setWhereClauses($where_clauses);
3545 return $where_clauses;
3548 function add_quotes($str) {
3553 * This function will rebuild the config file
3554 * @param $sugar_config
3555 * @param $sugar_version
3556 * @return bool true if successful
3558 function rebuildConfigFile($sugar_config, $sugar_version) {
3559 // add defaults to missing values of in-memory sugar_config
3560 $sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config );
3561 // need to override version with default no matter what
3562 $sugar_config['sugar_version'] = $sugar_version;
3564 ksort( $sugar_config );
3566 if( write_array_to_file( "sugar_config", $sugar_config, "config.php" ) ){
3575 * getJavascriptSiteURL
3576 * This function returns a URL for the client javascript calls to access
3577 * the site. It uses $_SERVER['HTTP_REFERER'] in the event that Proxy servers
3578 * are used to access the site. Thus, the hostname in the URL returned may
3579 * not always match that of $sugar_config['site_url']. Basically, the
3580 * assumption is that however the user accessed the website is how they
3581 * will continue to with subsequent javascript requests. If the variable
3582 * $_SERVER['HTTP_REFERER'] is not found then we default to old algorithm.
3583 * @return $site_url The url used to refer to the website
3585 function getJavascriptSiteURL() {
3586 global $sugar_config;
3587 if(!empty($_SERVER['HTTP_REFERER'])) {
3588 $url = parse_url($_SERVER['HTTP_REFERER']);
3589 $replacement_url = $url['scheme']."://".$url['host'];
3590 if(!empty($url['port']))
3591 $replacement_url .= ':'.$url['port'];
3592 $site_url = preg_replace('/^http[s]?\:\/\/[^\/]+/',$replacement_url,$sugar_config['site_url']);
3594 $site_url = preg_replace('/^http(s)?\:\/\/[^\/]+/',"http$1://".$_SERVER['HTTP_HOST'],$sugar_config['site_url']);
3595 if(!empty($_SERVER['SERVER_PORT']) &&$_SERVER['SERVER_PORT'] == '443') {
3596 $site_url = preg_replace('/^http\:/','https:',$site_url);
3599 $GLOBALS['log']->debug("getJavascriptSiteURL(), site_url=". $site_url);
3603 // works nicely with array_map() -- can be used to wrap single quotes around each element in an array
3604 function add_squotes($str) {
3605 return "'" . $str . "'";
3609 // recursive function to count the number of levels within an array
3610 function array_depth($array, $depth_count=-1, $depth_array=array()){
3612 if (is_array($array)){
3613 foreach ($array as $key => $value){
3614 $depth_array[] = array_depth($value, $depth_count);
3618 return $depth_count;
3620 foreach ($depth_array as $value){
3621 $depth_count = $value > $depth_count ? $value : $depth_count;
3623 return $depth_count;
3627 * Creates a new Group User
3628 * @param string $name Name of Group User
3629 * @return string GUID of new Group User
3631 function createGroupUser($name) {
3634 $group = new User();
3635 $group->user_name = $name;
3636 $group->last_name = $name;
3637 $group->is_group = 1;
3638 $group->deleted = 0;
3639 $group->status = 'Active'; // cn: bug 6711
3640 $group->setPreference('timezone', TimeDate::userTimezone());
3647 * Helper function to locate an icon file given only a name
3648 * Searches through the various paths for the file
3649 * @param string iconFileName The filename of the icon
3650 * @return string Relative pathname of the located icon, or '' if not found
3653 function _getIcon($iconFileName)
3655 $iconPath = SugarThemeRegistry::current()->getImageURL("icon_{$iconFileName}.gif");
3656 //First try un-ucfirst-ing the icon name
3657 if ( empty($iconPath) )
3658 $iconPath = SugarThemeRegistry::current()->getImageURL(
3659 "icon_" . strtolower(substr($iconFileName,0,1)).substr($iconFileName,1) . ".gif");
3660 //Next try removing the icon prefix
3661 if ( empty($iconPath) )
3662 $iconPath = SugarThemeRegistry::current()->getImageURL("{$iconFileName}.gif");
3667 * Function to grab the correct icon image for Studio
3668 * @param string $iconFileName Name of the icon file
3669 * @param string $altfilename Name of a fallback icon file (displayed if the imagefilename doesn't exist)
3670 * @param string $width Width of image
3671 * @param string $height Height of image
3672 * @param string $align Alignment of image
3673 * @return string $string <img> tag with corresponding image
3676 function getStudioIcon($iconFileName='', $altFileName='', $width='48', $height='48', $align='baseline' )
3678 global $app_strings, $theme;
3680 $iconPath = _getIcon($iconFileName);
3681 if(empty($iconPath)){
3682 $iconPath = _getIcon($altFileName);
3683 if (empty($iconPath))
3685 return $app_strings['LBL_NO_IMAGE'];
3688 return '<img border="0" src="'.$iconPath.'" width="'.$width.'" height="'.$height.'" align="'.$align.'">';
3692 * Function to grab the correct icon image for Dashlets Dialog
3693 * @param string $filename Location of the icon file
3694 * @param string $module Name of the module to fall back onto if file does not exist
3695 * @param string $width Width of image
3696 * @param string $height Height of image
3697 * @param string $align Alignment of image
3698 * @return string $string <img> tag with corresponding image
3701 function get_dashlets_dialog_icon($module='', $width='32', $height='32', $align='absmiddle'){
3702 global $app_strings, $theme;
3703 $icon_path = _getIcon($module . "_32");
3704 if (empty($icon_path))
3706 $icon_path = _getIcon($module);
3708 if(empty($icon_path)){
3709 $icon = $app_strings['LBL_NO_IMAGE'];
3712 $icon = '<img border="0" src="'.$icon_path.'" width="'.$width.'" height="'.$height.'" align="'.$align.'">';
3717 // works nicely to change UTF8 strings that are html entities - good for PDF conversions
3718 function html_entity_decode_utf8($string)
3721 // replace numeric entities
3722 //php will have issues with numbers with leading zeros, so do not include them in what we send to code2utf.
3723 $string = preg_replace('~�*([0-9a-f]+);~ei', 'code2utf(hexdec("\\1"))', $string);
3724 $string = preg_replace('~�*([0-9]+);~e', 'code2utf(\\1)', $string);
3725 // replace literal entities
3726 if (!isset($trans_tbl))
3728 $trans_tbl = array();
3729 foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key)
3730 $trans_tbl[$key] = utf8_encode($val);
3732 return strtr($string, $trans_tbl);
3735 // Returns the utf string corresponding to the unicode value
3736 function code2utf($num)
3738 if ($num < 128) return chr($num);
3739 if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
3740 if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
3741 if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
3745 function str_split_php4($string, $length = 1) {
3746 $string_length = strlen($string);
3749 if ($length > $string_length) {
3750 // use the string_length as the string is shorter than the length
3751 $length = $string_length;
3753 for ($cursor = 0; $cursor < $string_length; $cursor = $cursor + $length) {
3754 $return[] = substr($string, $cursor, $length);
3759 if (version_compare(phpversion(), '5.0.0', '<')) {
3760 function str_split($string, $length = 1) {
3761 return str_split_php4($string, $length);
3766 * Invoked when connected to mssql. checks if we have freetds version of mssql library.
3767 * the response is put into a global variable.
3769 function is_freetds() {
3772 if (isset($GLOBALS['mssql_library_version'])) {
3773 if ($GLOBALS['mssql_library_version']=='freetds') {
3781 $info=ob_get_contents();
3784 if (strpos($info,'FreeTDS') !== false) {
3785 $GLOBALS['mssql_library_version']='freetds';
3788 $GLOBALS['mssql_library_version']='regular';
3796 * stripos - Find position of first occurrence of a case-insensitive string
3798 * The function is being defined for systems with PHP version < 5.
3801 if (!function_exists("stripos")){
3802 function stripos($haystack,$needle,$offset=0){
3803 return strpos(strtolower($haystack),strtolower($needle),$offset);
3808 * Chart dashlet helper function that returns the correct CSS file, dependent on the current theme.
3810 * @todo this won't work completely right until we impliment css compression and combination
3811 * for now, we'll just include the last css file found.
3813 * @return chart.css file to use
3815 function chartStyle()
3817 return SugarThemeRegistry::current()->getCSSURL('chart.css');
3821 * Chart dashlet helper functions that returns the correct XML color file for charts,
3822 * dependent on the current theme.
3824 * @return sugarColors.xml to use
3826 function chartColors()
3828 if (SugarThemeRegistry::current()->getCSSURL('sugarColors.xml')=='')
3829 return SugarThemeRegistry::current()->getImageURL('sugarColors.xml');
3830 return SugarThemeRegistry::current()->getCSSURL('sugarColors.xml');
3832 /* End Chart Dashlet helper functions */
3835 * This function is designed to set up the php enviroment
3836 * for AJAX requests.
3839 function ajaxInit() {
3840 ini_set('display_errors', 'false');
3844 * Returns an absolute path from the given path, determining if it is relative or absolute
3846 * @param string $path
3849 function getAbsolutePath(
3851 $currentServer = false
3854 $path = trim($path);
3856 // try to match absolute paths like \\server\share, /directory or c:\
3857 if ( ( substr($path,0,2) == '\\\\' )
3858 || ( $path[0] == '/' )
3859 || preg_match('/^[A-z]:/i',$path)
3863 return getcwd().'/'.$path;
3867 * Returns the bean object of the given module
3869 * @deprecated use SugarModule::loadBean() instead
3870 * @param string $module
3877 return SugarModule::get($module)->loadBean();
3882 * Returns true if the application is being accessed on a touch screen interface ( like an iPad )
3884 function isTouchScreen()
3886 $ua = empty($_SERVER['HTTP_USER_AGENT']) ? "undefined" : strtolower($_SERVER['HTTP_USER_AGENT']);
3888 // first check if we have forced use of the touch enhanced interface
3889 if ( isset($_COOKIE['touchscreen']) && $_COOKIE['touchscreen'] == '1' ) {
3893 // next check if we should use the touch interface with our device
3894 if ( strpos($ua, 'ipad') !== false ) {
3902 * Returns the shortcut keys to access the shortcut links. Shortcut
3903 * keys vary depending on browser versions and operating systems.
3904 * @return String value of the shortcut keys
3906 function get_alt_hot_key() {
3908 if ( isset($_SERVER['HTTP_USER_AGENT']) )
3909 $ua = strtolower($_SERVER['HTTP_USER_AGENT']);
3910 $isMac = strpos($ua, 'mac') !== false;
3911 $isLinux = strpos($ua, 'linux') !== false;
3913 if(!$isMac && !$isLinux && strpos($ua, 'mozilla') !== false) {
3914 if(preg_match('/firefox\/(\d)?\./', $ua, $matches)) {
3915 return $matches[1] < 2 ? 'Alt+' : 'Alt+Shift+';
3918 return $isMac ? 'Ctrl+' : 'Alt+';
3921 function can_start_session(){
3922 if(!empty($_GET['PHPSESSID'])) {
3925 $session_id = session_id();
3926 return empty($session_id) ? true : false;
3929 function load_link_class($properties){
3931 if(!empty($properties['link_class']) && !empty($properties['link_file'])){
3932 require_once($properties['link_file']);
3933 $class = $properties['link_class'];
3939 function inDeveloperMode()
3941 return isset($GLOBALS['sugar_config']['developerMode']) && $GLOBALS['sugar_config']['developerMode'];
3945 * Filter the protocol list for inbound email accounts.
3947 * @param array $protocol
3949 function filterInboundEmailPopSelection($protocol)
3951 if ( !isset($GLOBALS['sugar_config']['allow_pop_inbound']) || ! $GLOBALS['sugar_config']['allow_pop_inbound'] )
3953 if( isset($protocol['pop3']) )
3954 unset($protocol['pop3']);
3957 $protocol['pop3'] = 'POP3';
3963 * The function is used because currently we are not supporting mbstring.func_overload
3964 * For some user using mssql without FreeTDS, they may store multibyte charaters in varchar using latin_general collation. It cannot store so many mutilbyte characters, so we need to use strlen.
3965 * The varchar in MySQL, Orcale, and nvarchar in FreeTDS, we can store $length mutilbyte charaters in it. we need mb_substr to keep more info.
3966 * @returns the substred strings.
3968 function sugar_substr($string, $length, $charset='UTF-8') {
3969 if($GLOBALS['db']->dbType == 'mssql' && empty($GLOBALS['db']->isFreeTDS)) {
3970 if(strlen($string) > $length) {
3971 $string = trim(substr(trim($string),0,$length));
3975 if(mb_strlen($string,$charset) > $length) {
3976 $string = trim(mb_substr(trim($string),0,$length,$charset));
3983 * The function is used because on FastCGI enviroment, the ucfirst(Chinese Characters) will produce bad charcters.
3984 * This will work even without setting the mbstring.*encoding
3986 function sugar_ucfirst($string, $charset='UTF-8') {
3987 return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset) . mb_substr($string, 1, mb_strlen($string), $charset);
3994 function unencodeMultienum($string) {
3995 if (is_array($string))
3999 if (substr($string, 0 ,1) == "^" && substr($string, -1) == "^") {
4000 $string = substr(substr($string, 1), 0, strlen($string) -2);
4003 return explode('^,^', $string);
4006 function encodeMultienumValue($arr) {
4007 if (!is_array($arr))
4013 $string = "^" . implode('^,^', $arr) . "^";
4019 * create_export_query is used for export and massupdate
4020 * We haven't handle the these fields: $field['type'] == 'relate' && isset($field['link']
4021 * This function will correct the where clause and output necessary join condition for them
4022 * @param $module: the module name
4023 * @param $searchFields: searchFields which is got after $searchForm->populateFromArray()
4024 * @param $where: where clauses
4025 * @return $ret_array['where']: corrected where clause
4026 * @return $ret_array['join']: extra join condition
4028 function create_export_query_relate_link_patch($module, $searchFields, $where){
4029 if(file_exists('modules/'.$module.'/SearchForm.html')){
4030 $ret_array['where'] = $where;
4033 $seed = loadBean($module);
4034 foreach($seed->field_defs as $name=>$field)
4037 if( $field['type'] == 'relate' && isset($field['link']) && !empty($searchFields[$name]['value']) ){
4038 $seed->load_relationship($field['link']);
4040 if(empty($join_type))
4042 $params['join_type'] = ' LEFT JOIN ';
4046 $params['join_type'] = $join_type;
4048 if(isset($data['join_name']))
4050 $params['join_table_alias'] = $field['join_name'];
4054 $params['join_table_alias'] = 'join_'.$field['name'];
4057 if(isset($data['join_link_name']))
4059 $params['join_table_link_alias'] = $field['join_link_name'];
4063 $params['join_table_link_alias'] = 'join_link_'.$field['name'];
4065 $join = $seed->$field['link']->getJoin($params, true);
4066 $join_table_alias = 'join_'.$field['name'];
4067 if(isset($field['db_concat_fields'])){
4068 $db_field = db_concat($join_table_alias, $field['db_concat_fields']);
4069 $where = preg_replace('/'.$field['name'].'/', $db_field, $where);
4071 $where = preg_replace('/(^|[\s(])' . $field['name'] . '/', '${1}' . $join_table_alias . '.'.$field['rname'], $where);
4075 $ret_array = array('where'=>$where, 'join'=>$join['join']);
4080 * We need to clear all the js cache files, including the js language files in serval places in MB. So I extract them into a util function here.
4081 * @Depends on QuickRepairAndRebuild.php
4082 * @Relate bug 30642 ,23177
4084 function clearAllJsAndJsLangFilesWithoutOutput(){
4085 global $current_language , $mod_strings;
4086 $MBmodStrings = $mod_strings;
4087 $mod_strings = return_module_language ( $current_language, 'Administration' ) ;
4088 include_once ('modules/Administration/QuickRepairAndRebuild.php') ;
4089 $repair = new RepairAndClear();
4090 $repair->module_list = array();
4091 $repair->show_output = false;
4092 $repair->clearJsLangFiles();
4093 $repair->clearJsFiles();
4094 $mod_strings = $MBmodStrings;
4098 * This function will allow you to get a variable value from query string
4100 function getVariableFromQueryString($variable, $string){
4102 $number = preg_match("/{$variable}=([a-zA-Z0-9_-]+)[&]?/", $string, $matches);
4112 * should_hide_iframes
4113 * This is a helper method to determine whether or not to show iframes (My Sites) related
4114 * information in the application.
4116 * @return boolean flag indicating whether or not iframes module should be hidden
4118 function should_hide_iframes() {
4119 //Remove the MySites module
4120 if(file_exists('modules/iFrames/iFrame.php')) {
4121 if(!class_exists("iFrame")) {
4122 require_once('modules/iFrames/iFrame.php');
4130 * Given a version such as 5.5.0RC1 return RC. If we have a version such as: 5.5 then return GA
4132 * @param string $version
4133 * @return string RC, BETA, GA
4135 function getVersionStatus($version){
4136 if(preg_match('/^[\d\.]+?([a-zA-Z]+?)[\d]*?$/si', $version, $matches)) {
4137 return strtoupper($matches[1]);
4144 * Return the numeric portion of a version. For example if passed 5.5.0RC1 then return 5.5. If given
4145 * 5.5.1RC1 then return 5.5.1
4147 * @param string $version
4150 function getMajorMinorVersion($version){
4151 if(preg_match('/^([\d\.]+).*$/si', $version, $matches2)){
4152 $version = $matches2[1];
4153 $arr = explode('.', $version);
4154 if(count($arr) > 2){
4156 $version = substr($version, 0, 3);
4164 * Return string composed of seconds & microseconds of current time, without dots
4167 function sugar_microtime()
4169 $now = explode(' ', microtime());
4170 $unique_id = $now[1].str_replace('.', '', $now[0]);
4175 * Extract urls from a piece of text
4177 * @return array of urls found in $string
4179 function getUrls($string)
4181 $lines = explode("<br>", trim($string));
4183 foreach($lines as $line){
4184 $regex = '/http?\:\/\/[^\" ]+/i';
4185 preg_match_all($regex, $line, $matches);
4186 foreach($matches[0] as $match){
4195 * Sanitize image file from hostile content
4196 * @param string $path Image file
4197 * @param bool $jpeg Accept only JPEGs?
4199 function verify_image_file($path, $jpeg = false)
4201 if(function_exists('imagepng') && function_exists('imagejpeg') && function_exists('imagecreatefromstring')) {
4202 $img = imagecreatefromstring(file_get_contents($path));
4206 $img_size = getimagesize($path);
4207 $filetype = $img_size['mime'];
4208 //if filetype is jpeg or if we are only allowing jpegs, create jpg image
4209 if($filetype == "image/jpeg" || $jpeg) {
4210 if(imagejpeg($img, $path)) {
4213 } elseif ($filetype == "image/png") { // else if the filetype is png, create png
4214 imagealphablending($img, true);
4215 imagesavealpha($img, true);
4216 if(imagepng($img, $path)) {
4223 // check image manually
4224 $fp = fopen($path, "r");
4225 if(!$fp) return false;
4226 $data = fread($fp, 4096);
4228 if(preg_match("/<(html|!doctype|script|body|head|plaintext|table|img |pre(>| )|frameset|iframe|object|link|base|style|font|applet|meta|center|form|isindex)/i",
4230 $GLOBALS['log']->info("Found {$m[0]} in $path, not allowing upload");
4239 * Verify uploaded image
4240 * Verifies that image has proper extension, MIME type and doesn't contain hostile contant
4241 * @param string $path Image path
4242 * @param bool $jpeg_only Accept only JPEGs?
4244 function verify_uploaded_image($path, $jpeg_only = false)
4246 $supportedExtensions = array('jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg');
4248 $supportedExtensions['png'] = 'image/png';
4251 if(!file_exists($path) || !is_file($path)) {
4255 $img_size = getimagesize($path);
4256 $filetype = $img_size['mime'];
4257 $ext = end(explode(".", $path));
4258 if(substr_count('..', $path) > 0 || $ext === $path || !in_array(strtolower($ext), array_keys($supportedExtensions)) ||
4259 !in_array($filetype, array_values($supportedExtensions))) {
4262 return verify_image_file($path, $jpeg_only);