PageRenderTime 70ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/include/utils.php

https://github.com/mitani/dashlet-subpanels
PHP | 4311 lines | 3516 code | 444 blank | 351 comment | 279 complexity | e92a0ef36a5ca6eb88da8674370551ee MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /*********************************************************************************
  3. * SugarCRM is a customer relationship management program developed by
  4. * SugarCRM, Inc. Copyright (C) 2004 - 2009 SugarCRM Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU 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.
  12. *
  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 General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU 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
  21. * 02110-1301 USA.
  22. *
  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.
  25. *
  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 General Public License version 3.
  29. *
  30. * In accordance with Section 7(b) of the GNU 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. ********************************************************************************/
  36. /*********************************************************************************
  37. * Description: Includes generic helper functions used throughout the application.
  38. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  39. * All Rights Reserved.
  40. * Contributor(s): ______________________________________..
  41. ********************************************************************************/
  42. require_once('include/SugarObjects/SugarConfig.php');
  43. require_once('include/utils/external_cache.php');
  44. require_once('include/utils/security_utils.php');
  45. function make_sugar_config(&$sugar_config)
  46. {
  47. /* used to convert non-array config.php file to array format */
  48. global $admin_export_only;
  49. global $cache_dir;
  50. global $calculate_response_time;
  51. global $create_default_user;
  52. global $dateFormats;
  53. global $dbconfig;
  54. global $dbconfigoption;
  55. global $default_action;
  56. global $default_charset;
  57. global $default_currency_name;
  58. global $default_currency_symbol;
  59. global $default_currency_iso4217;
  60. global $defaultDateFormat;
  61. global $default_language;
  62. global $default_module;
  63. global $default_password;
  64. global $default_permission_mode;
  65. global $default_theme;
  66. global $defaultTimeFormat;
  67. global $default_user_is_admin;
  68. global $default_user_name;
  69. global $disable_export;
  70. global $disable_persistent_connections;
  71. global $display_email_template_variable_chooser;
  72. global $display_inbound_email_buttons;
  73. global $history_max_viewed;
  74. global $host_name;
  75. global $import_dir;
  76. global $languages;
  77. global $list_max_entries_per_page;
  78. global $lock_default_user_name;
  79. global $log_memory_usage;
  80. global $requireAccounts;
  81. global $RSS_CACHE_TIME;
  82. global $session_dir;
  83. global $site_URL;
  84. global $site_url;
  85. global $sugar_version;
  86. global $timeFormats;
  87. global $tmp_dir;
  88. global $translation_string_prefix;
  89. global $unique_key;
  90. global $upload_badext;
  91. global $upload_dir;
  92. global $upload_maxsize;
  93. global $import_max_execution_time;
  94. global $list_max_entries_per_subpanel;
  95. global $passwordsetting;
  96. // assumes the following variables must be set:
  97. // $dbconfig, $dbconfigoption, $cache_dir, $import_dir, $session_dir, $site_URL, $tmp_dir, $upload_dir
  98. $sugar_config = array (
  99. 'admin_export_only' => empty($admin_export_only) ? false : $admin_export_only,
  100. 'export_delimiter' => empty($export_delimiter) ? ',' : $export_delimiter,
  101. 'cache_dir' => empty($cache_dir) ? $_GLOBALS['sugar_config']['cache_dir'] : $cache_dir,
  102. 'calculate_response_time' => empty($calculate_response_time) ? true : $calculate_response_time,
  103. 'create_default_user' => empty($create_default_user) ? false : $create_default_user,
  104. 'date_formats' => empty($dateFormats) ? array(
  105. 'Y-m-d'=>'2006-12-23',
  106. 'd-m-Y' => '23-12-2006',
  107. 'm-d-Y'=>'12-23-2006',
  108. 'Y/m/d'=>'2006/12/23',
  109. 'd/m/Y' => '23/12/2006',
  110. 'm/d/Y'=>'12/23/2006',
  111. 'Y.m.d' => '2006.12.23',
  112. 'd.m.Y' => '23.12.2006',
  113. 'm.d.Y' => '12.23.2006'
  114. ) : $dateFormats,
  115. 'dbconfig' => $dbconfig, // this must be set!!
  116. 'dbconfigoption' => $dbconfigoption, // this must be set!!
  117. 'default_action' => empty($default_action) ? 'index' : $default_action,
  118. 'default_charset' => empty($default_charset) ? 'UTF-8' : $default_charset,
  119. 'default_currency_name' => empty($default_currency_name) ? 'US Dollar' : $default_currency_name,
  120. 'default_currency_symbol' => empty($default_currency_symbol) ? '$' : $default_currency_symbol,
  121. 'default_currency_iso4217' => empty($default_currency_iso4217) ? '$' : $default_currency_iso4217,
  122. 'default_date_format' => empty($defaultDateFormat) ? 'm/d/Y' : $defaultDateFormat,
  123. 'default_language' => empty($default_language) ? 'en_us' : $default_language,
  124. 'default_module' => empty($default_module) ? 'Home' : $default_module,
  125. 'default_password' => empty($default_password) ? '' : $default_password,
  126. 'default_permissions' => array (
  127. 'dir_mode' => 02770,
  128. 'file_mode' => 0660,
  129. 'chown' => '',
  130. 'chgrp' => '',
  131. ),
  132. 'default_theme' => empty($default_theme) ? 'Sugar' : $default_theme,
  133. 'default_time_format' => empty($defaultTimeFormat) ? 'h:ia' : $defaultTimeFormat,
  134. 'default_user_is_admin' => empty($default_user_is_admin) ? false : $default_user_is_admin,
  135. 'default_user_name' => empty($default_user_name) ? '' : $default_user_name,
  136. 'disable_export' => empty($disable_export) ? false : $disable_export,
  137. 'disable_persistent_connections' => empty($disable_persistent_connections) ? false : $disable_persistent_connections,
  138. 'display_email_template_variable_chooser' => empty($display_email_template_variable_chooser) ? false : $display_email_template_variable_chooser,
  139. 'display_inbound_email_buttons' => empty($display_inbound_email_buttons) ? false : $display_inbound_email_buttons,
  140. 'history_max_viewed' => empty($history_max_viewed) ? 10 : $history_max_viewed,
  141. 'host_name' => empty($host_name) ? 'localhost' : $host_name,
  142. 'import_dir' => $import_dir, // this must be set!!
  143. 'import_max_records_per_file' => '1000',
  144. 'languages' => empty($languages) ? array('en_us' => 'English (US)') : $languages,
  145. 'list_max_entries_per_page' => empty($list_max_entries_per_page) ? 20 : $list_max_entries_per_page,
  146. 'list_max_entries_per_subpanel' => empty($list_max_entries_per_subpanel) ? 10 : $list_max_entries_per_subpanel,
  147. 'lock_default_user_name' => empty($lock_default_user_name) ? false : $lock_default_user_name,
  148. 'log_memory_usage' => empty($log_memory_usage) ? false : $log_memory_usage,
  149. 'portal_view' => 'single_user',
  150. 'resource_management' => array (
  151. 'special_query_limit' => 50000,
  152. 'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'),
  153. 'default_limit' => 1000,
  154. ),
  155. 'require_accounts' => empty($requireAccounts) ? true : $requireAccounts,
  156. 'rss_cache_time' => empty($RSS_CACHE_TIME) ? '10800' : $RSS_CACHE_TIME,
  157. 'session_dir' => $session_dir, // this must be set!!
  158. 'site_url' => empty($site_URL) ? $site_url : $site_URL, // this must be set!!
  159. 'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable
  160. 'showThemePicker' => true,
  161. 'sugar_version' => empty($sugar_version) ? 'unknown' : $sugar_version,
  162. 'time_formats' => empty($timeFormats) ? array (
  163. 'H:i'=>'23:00', 'h:ia'=>'11:00pm', 'h:iA'=>'11:00PM',
  164. 'H.i'=>'23.00', 'h.ia'=>'11.00pm', 'h.iA'=>'11.00PM' ) : $timeFormats,
  165. 'tmp_dir' => $tmp_dir, // this must be set!!
  166. 'translation_string_prefix' => empty($translation_string_prefix) ? false : $translation_string_prefix,
  167. 'unique_key' => empty($unique_key) ? md5(create_guid()) : $unique_key,
  168. 'upload_badext' => empty($upload_badext) ? array (
  169. 'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py',
  170. 'asp', 'cfm', 'js', 'vbs', 'html', 'htm' ) : $upload_badext,
  171. 'upload_dir' => $upload_dir, // this must be set!!
  172. 'upload_maxsize' => empty($upload_maxsize) ? 3000000 : $upload_maxsize,
  173. 'import_max_execution_time' => empty($import_max_execution_time) ? 3600 : $import_max_execution_time,
  174. 'lock_homepage' => false,
  175. 'lock_subpanels' => false,
  176. 'max_dashlets_homepage' => 15,
  177. 'dashlet_display_row_options' => array('1','3','5','10'),
  178. 'default_max_tabs' => empty($max_tabs) ? '12' : $max_tabs,
  179. 'default_max_subtabs' => empty($max_subtabs) ? '12' : $max_subtabs,
  180. 'default_subpanel_tabs' => empty($subpanel_tabs) ? true : $subpanel_tabs,
  181. 'default_subpanel_links' => empty($subpanel_links) ? false : $subpanel_links,
  182. 'default_swap_last_viewed' => empty($swap_last_viewed) ? false : $swap_last_viewed,
  183. 'default_swap_shortcuts' => empty($swap_shortcuts) ? false : $swap_shortcuts,
  184. 'default_navigation_paradigm' => empty($navigation_paradigm) ? 'm' : $navigation_paradigm,
  185. 'js_lang_version' => 1,
  186. 'passwordsetting' => empty($passwordsetting) ? array (
  187. 'minpwdlength' => '',
  188. 'maxpwdlength' => '',
  189. 'oneupper' => '',
  190. 'onelower' => '',
  191. 'onenumber' => '',
  192. 'onespecial' => '',
  193. 'generatepasswordtmpl' => '',
  194. 'lostpasswordtmpl' => '',
  195. //'prohibitedcaracters' => '@\\ ?+:$',
  196. //'neededcaracters' => 'ef',
  197. //'firstnameallowed' => '2',
  198. //'lastnameallowed' => '2',
  199. 'customregex' => '',
  200. 'regexcomment' => '',
  201. 'linkexpiration' => '1',
  202. 'linkexpirationtime' => '30',
  203. 'linkexpirationtype' => '1',
  204. 'userexpiration' => '0',
  205. 'userexpirationtime' => '',
  206. 'userexpirationtype' => '1',
  207. 'userexpirationlogin' => '',
  208. //'systexpiration' => '0',
  209. //'systexpirationtime' => '',
  210. //'systexpirationtype' => '1',
  211. //'systexpirationlogin' => '',
  212. 'lockoutexpiration' => '0',
  213. 'lockoutexpirationtime' => '',
  214. 'lockoutexpirationtype' => '1',
  215. 'lockoutexpirationlogin' => '',
  216. ) : $passwordsetting
  217. );
  218. }
  219. function get_sugar_config_defaults() {
  220. global $locale;
  221. /**
  222. * used for getting base values for array style config.php. used by the
  223. * installer and to fill in new entries on upgrades. see also:
  224. * sugar_config_union
  225. */
  226. $sugar_config_defaults = array (
  227. 'admin_export_only' => false,
  228. 'export_delimiter' => ',',
  229. 'calculate_response_time' => true,
  230. 'create_default_user' => false,
  231. 'date_formats' => array (
  232. 'Y-m-d' => '2006-12-23', 'm-d-Y' => '12-23-2006', 'd-m-Y' => '23-12-2006',
  233. 'Y/m/d' => '2006/12/23', 'm/d/Y' => '12/23/2006', 'd/m/Y' => '23/12/2006',
  234. 'Y.m.d' => '2006.12.23', 'd.m.Y' => '23.12.2006', 'm.d.Y' => '12.23.2006',),
  235. 'dbconfigoption' => array (
  236. 'persistent' => true,
  237. 'autofree' => false,
  238. 'debug' => 0,
  239. 'seqname_format' => '%s_seq',
  240. 'portability' => 0,
  241. 'ssl' => false ),
  242. 'default_action' => 'index',
  243. 'default_charset' => return_session_value_or_default('default_charset',
  244. 'UTF-8'),
  245. 'default_currency_name' => return_session_value_or_default('default_currency_name', 'US Dollar'),
  246. 'default_currency_symbol' => return_session_value_or_default('default_currency_symbol', '$'),
  247. 'default_currency_iso4217' => return_session_value_or_default('default_currency_iso4217', 'USD'),
  248. 'default_date_format' => 'm/d/Y',
  249. 'default_language' => return_session_value_or_default('default_language',
  250. 'en_us'),
  251. 'default_module' => 'Home',
  252. 'default_password' => '',
  253. 'default_permissions' => array (
  254. 'dir_mode' => 02770,
  255. 'file_mode' => 0660,
  256. 'user' => '',
  257. 'group' => '',
  258. ),
  259. 'default_theme' => return_session_value_or_default('site_default_theme', 'Sugar'),
  260. 'default_time_format' => 'h:ia',
  261. 'default_user_is_admin' => false,
  262. 'default_user_name' => '',
  263. 'disable_export' => false,
  264. 'disable_persistent_connections' =>
  265. return_session_value_or_default('disable_persistent_connections',
  266. 'false'),
  267. 'display_email_template_variable_chooser' => false,
  268. 'display_inbound_email_buttons' => false,
  269. 'dump_slow_queries' => false,
  270. 'email_default_editor' => 'html',
  271. 'email_default_client' => 'sugar',
  272. 'email_default_delete_attachments' => true,
  273. 'email_num_autoreplies_24_hours' => 10,
  274. 'history_max_viewed' => 10,
  275. 'installer_locked' => true,
  276. 'import_max_records_per_file' => '1000',
  277. 'languages' => array('en_us' => 'English (US)'),
  278. 'large_scale_test' => false,
  279. 'list_max_entries_per_page' => 20,
  280. 'list_max_entries_per_subpanel' => 10,
  281. 'lock_default_user_name' => false,
  282. 'log_memory_usage' => false,
  283. 'login_nav' => false,
  284. 'portal_view' => 'single_user',
  285. 'resource_management' => array (
  286. 'special_query_limit' => 50000,
  287. 'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'),
  288. 'default_limit' => 1000,
  289. ),
  290. 'require_accounts' => true,
  291. 'rss_cache_time' => return_session_value_or_default('rss_cache_time',
  292. '10800'),
  293. 'save_query' => 'all',
  294. 'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable
  295. 'showThemePicker' => true,
  296. 'slow_query_time_msec' => '100',
  297. 'sugarbeet' => true,
  298. 'time_formats' => array (
  299. 'H:i'=>'23:00', 'h:ia'=>'11:00pm', 'h:iA'=>'11:00PM',
  300. 'H.i'=>'23.00', 'h.ia'=>'11.00pm', 'h.iA'=>'11.00PM' ),
  301. 'translation_string_prefix' =>
  302. return_session_value_or_default('translation_string_prefix', false),
  303. 'upload_badext' => array (
  304. 'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py',
  305. 'asp', 'cfm', 'js', 'vbs', 'html', 'htm' ),
  306. 'upload_maxsize' => 3000000,
  307. 'import_max_execution_time' => 3600,
  308. 'use_php_code_json' => returnPhpJsonStatus(),
  309. 'verify_client_ip' => true,
  310. 'js_custom_version' => '',
  311. 'js_lang_version' => 1,
  312. 'default_number_grouping_seperator' => ',',
  313. 'default_decimal_seperator' => '.',
  314. 'lock_homepage' => false,
  315. 'lock_subpanels' => false,
  316. 'max_dashlets_homepage' => '15',
  317. 'default_max_tabs' => '12',
  318. 'default_max_subtabs' => '12',
  319. 'dashlet_display_row_options' => array('1','3','5','10'),
  320. 'default_subpanel_tabs' => true,
  321. 'default_subpanel_links' => false,
  322. 'default_swap_last_viewed' => false,
  323. 'default_swap_shortcuts' => false,
  324. 'default_navigation_paradigm' => 'm',
  325. 'admin_access_control' => false,
  326. 'use_common_ml_dir' => false,
  327. 'common_ml_dir' => '',
  328. 'vcal_time' => '2',
  329. 'passwordsetting' => array (
  330. 'minpwdlength' => '',
  331. 'maxpwdlength' => '',
  332. 'oneupper' => '',
  333. 'onelower' => '',
  334. 'onenumber' => '',
  335. 'onespecial' => '',
  336. 'generatepasswordtmpl' => '',
  337. 'lostpasswordtmpl' => '',
  338. //'prohibitedcaracters' => '@\\ ?+:$',
  339. //'neededcaracters' => 'ef',
  340. //'firstnameallowed' => '2',
  341. //'lastnameallowed' => '2',
  342. 'customregex' => '',
  343. 'regexcomment' => '',
  344. 'linkexpiration' => '1',
  345. 'linkexpirationtime' => '30',
  346. 'linkexpirationtype' => '1',
  347. 'userexpiration' => '0',
  348. 'userexpirationtime' => '',
  349. 'userexpirationtype' => '1',
  350. 'userexpirationlogin' => '',
  351. //'systexpiration' => '0',
  352. //'systexpirationtime' => '',
  353. //'systexpirationtype' => '1',
  354. //'systexpirationlogin' => '',
  355. 'lockoutexpiration' => '0',
  356. 'lockoutexpirationtime' => '',
  357. 'lockoutexpirationtype' => '1',
  358. 'lockoutexpirationlogin' => '',
  359. ),
  360. );
  361. if(!is_object($locale)) {
  362. if(!class_exists('Localization')) {
  363. }
  364. $locale = new Localization();
  365. }
  366. $sugar_config_defaults['default_currencies'] = $locale->getDefaultCurrencies();
  367. $sugar_config_defaults = sugarArrayMerge($locale->getLocaleConfigDefaults(), $sugar_config_defaults);
  368. return( $sugar_config_defaults );
  369. }
  370. function load_menu($path){
  371. global $module_menu;
  372. if(file_exists($path . 'Menu.php'))
  373. {
  374. require_once($path . 'Menu.php');
  375. }
  376. if(file_exists('custom/' . $path . 'Ext/Menus/menu.ext.php'))
  377. {
  378. require_once('custom/' . $path . 'Ext/Menus/menu.ext.php');
  379. }
  380. if(file_exists('custom/application/Ext/Menus/menu.ext.php'))
  381. {
  382. require_once('custom/application/Ext/Menus/menu.ext.php');
  383. }
  384. return $module_menu;
  385. }
  386. function sugar_config_union( $default, $override ){
  387. // a little different then array_merge and array_merge_recursive. we want
  388. // the second array to override the first array if the same value exists,
  389. // otherwise merge the unique keys. it handles arrays of arrays recursively
  390. // might be suitable for a generic array_union
  391. if( !is_array( $override ) ){
  392. $override = array();
  393. }
  394. foreach( $default as $key => $value ){
  395. if( !array_key_exists($key, $override) ){
  396. $override[$key] = $value;
  397. }
  398. else if( is_array( $key ) ){
  399. $override[$key] = sugar_config_union( $value, $override[$key] );
  400. }
  401. }
  402. return( $override );
  403. }
  404. function make_not_writable( $file ){
  405. // Returns true if the given file/dir has been made not writable
  406. $ret_val = false;
  407. if( is_file($file) || is_dir($file) ){
  408. if( !is_writable($file) ){
  409. $ret_val = true;
  410. }
  411. else {
  412. $original_fileperms = fileperms($file);
  413. // take away writable permissions
  414. $new_fileperms = $original_fileperms & ~0x0092;
  415. @sugar_chmod($file, $new_fileperms);
  416. if( !is_writable($file) ){
  417. $ret_val = true;
  418. }
  419. }
  420. }
  421. return $ret_val;
  422. }
  423. /** This function returns the name of the person.
  424. * It currently returns "first last". It should not put the space if either name is not available.
  425. * It should not return errors if either name is not available.
  426. * If no names are present, it will return ""
  427. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  428. * All Rights Reserved.
  429. * Contributor(s): ______________________________________..
  430. */
  431. function return_name($row, $first_column, $last_column)
  432. {
  433. $first_name = "";
  434. $last_name = "";
  435. $full_name = "";
  436. if(isset($row[$first_column]))
  437. {
  438. $first_name = stripslashes($row[$first_column]);
  439. }
  440. if(isset($row[$last_column]))
  441. {
  442. $last_name = stripslashes($row[$last_column]);
  443. }
  444. $full_name = $first_name;
  445. // If we have a first name and we have a last name
  446. if($full_name != "" && $last_name != "")
  447. {
  448. // append a space, then the last name
  449. $full_name .= " ".$last_name;
  450. }
  451. // If we have no first name, but we have a last name
  452. else if($last_name != "")
  453. {
  454. // append the last name without the space.
  455. $full_name .= $last_name;
  456. }
  457. return $full_name;
  458. }
  459. function get_languages()
  460. {
  461. global $sugar_config;
  462. return $sugar_config['languages'];
  463. }
  464. function get_language_display($key)
  465. {
  466. global $sugar_config;
  467. return $sugar_config['languages'][$key];
  468. }
  469. function get_assigned_user_name($assigned_user_id, $is_group = '') {
  470. static $saved_user_list = null;
  471. if(empty($saved_user_list)) {
  472. $saved_user_list = get_user_array(false, '', '', false, null, $is_group);
  473. }
  474. if(isset($saved_user_list[$assigned_user_id])) {
  475. return $saved_user_list[$assigned_user_id];
  476. }
  477. return '';
  478. }
  479. /**
  480. * retrieves the user_name column value (login)
  481. * @param string id GUID of user
  482. * @return string
  483. */
  484. function get_user_name($id) {
  485. global $db;
  486. if(empty($db))
  487. $db = DBManagerFactory::getInstance();
  488. $q = "SELECT user_name FROM users WHERE id='{$id}'";
  489. $r = $db->query($q);
  490. $a = $db->fetchByAssoc($r);
  491. return (empty($a)) ? '' : $a['user_name'];
  492. }
  493. //TODO Update to use global cache
  494. 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) {
  495. global $locale;
  496. global $sugar_config;
  497. if(empty($locale)) {
  498. $locale = new Localization();
  499. }
  500. if($from_cache)
  501. $user_array = get_register_value('user_array', $add_blank. $status . $assigned_user);
  502. if(!isset($user_array)) {
  503. $db = DBManagerFactory::getInstance();
  504. $temp_result = Array();
  505. // Including deleted users for now.
  506. if (empty($status)) {
  507. $query = "SELECT id, first_name, last_name, user_name from users WHERE 1=1".$is_group;
  508. }
  509. else {
  510. $query = "SELECT id, first_name, last_name, user_name from users WHERE status='$status'".$is_group;
  511. }
  512. if (!empty($user_name_begins)) {
  513. $query .= " AND user_name LIKE '$user_name_begins%' ";
  514. }
  515. if (!empty($assigned_user)) {
  516. $query .= " OR id='$assigned_user'";
  517. }
  518. $query = $query.' ORDER BY user_name ASC';
  519. $GLOBALS['log']->debug("get_user_array query: $query");
  520. $result = $db->query($query, true, "Error filling in user array: ");
  521. if ($add_blank==true) {
  522. // Add in a blank row
  523. $temp_result[''] = '';
  524. }
  525. // Get the id and the name.
  526. while($row = $db->fetchByAssoc($result)) {
  527. if($use_real_name == true || showFullName()) {
  528. if(isset($row['last_name'])) { // cn: we will ALWAYS have both first_name and last_name (empty value if blank in db)
  529. $temp_result[$row['id']] = $locale->getLocaleFormattedName($row['first_name'],$row['last_name']);
  530. } else {
  531. $temp_result[$row['id']] = $row['user_name'];
  532. }
  533. } else {
  534. $temp_result[$row['id']] = $row['user_name'];
  535. }
  536. }
  537. $user_array = $temp_result;
  538. if($from_cache)
  539. set_register_value('user_array', $add_blank. $status . $assigned_user, $temp_result);
  540. }
  541. return $user_array;
  542. }
  543. /**
  544. * uses a different query to return a list of users than get_user_array()
  545. * @param args string where clause entry
  546. * @return array Array of Users' details that match passed criteria
  547. */
  548. function getUserArrayFromFullName($args) {
  549. global $locale;
  550. $db = DBManagerFactory::getInstance();
  551. $argArray = array();
  552. if(strpos($args, " ")) {
  553. $argArray = explode(" ", $args);
  554. } else {
  555. $argArray[] = $args;
  556. }
  557. $inClause = '';
  558. foreach($argArray as $arg) {
  559. if(!empty($inClause)) {
  560. $inClause .= ' OR ';
  561. }
  562. if(empty($arg))
  563. continue;
  564. $inClause .= "first_name LIKE '{$arg}%' OR last_name LIKE '{$arg}%'";
  565. }
  566. $query = "SELECT id, first_name, last_name, user_name FROM users WHERE status='Active' AND deleted=0 AND ";
  567. $query .= $inClause;
  568. $query .= " ORDER BY last_name ASC";
  569. $r = $db->query($query);
  570. $ret = array();
  571. while($a = $db->fetchByAssoc($r)) {
  572. $ret[$a['id']] = $locale->getLocaleFormattedName($a['first_name'], $a['last_name']);
  573. }
  574. return $ret;
  575. }
  576. /**
  577. *
  578. * based on user pref then system pref
  579. */
  580. function showFullName() {
  581. global $sugar_config;
  582. global $current_user;
  583. static $showFullName = null;
  584. if (is_null($showFullName)) {
  585. $sysPref = (isset($sugar_config['use_real_names']) && $sugar_config['use_real_names'] == true) ? true : false;
  586. $userPref = (is_object($current_user)) ? $current_user->getPreference('use_real_names') : null;
  587. if($userPref != null) {
  588. $bool = ($userPref == 'on') ? true : false;
  589. $showFullName = $bool;
  590. } else {
  591. $showFullName = $sysPref;
  592. }
  593. }
  594. return $showFullName;
  595. }
  596. function clean($string, $maxLength)
  597. {
  598. $string = substr($string, 0, $maxLength);
  599. return escapeshellcmd($string);
  600. }
  601. /**
  602. * Copy the specified request variable to the member variable of the specified object.
  603. * Do no copy if the member variable is already set.
  604. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  605. * All Rights Reserved.
  606. * Contributor(s): ______________________________________..
  607. */
  608. function safe_map($request_var, & $focus, $always_copy = false)
  609. {
  610. safe_map_named($request_var, $focus, $request_var, $always_copy);
  611. }
  612. /**
  613. * Copy the specified request variable to the member variable of the specified object.
  614. * Do no copy if the member variable is already set.
  615. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  616. * All Rights Reserved.
  617. * Contributor(s): ______________________________________..
  618. */
  619. function safe_map_named($request_var, & $focus, $member_var, $always_copy)
  620. {
  621. if (isset($_REQUEST[$request_var]) && ($always_copy || is_null($focus->$member_var))) {
  622. $GLOBALS['log']->debug("safe map named called assigning '{$_REQUEST[$request_var]}' to $member_var");
  623. $focus->$member_var = $_REQUEST[$request_var];
  624. }
  625. }
  626. /** This function retrieves an application language file and returns the array of strings included in the $app_list_strings var.
  627. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  628. * All Rights Reserved.
  629. * Contributor(s): ______________________________________..
  630. * If you are using the current language, do not call this function unless you are loading it for the first time */
  631. function return_app_list_strings_language($language) {
  632. global $app_list_strings;
  633. global $sugar_config;
  634. $cache_key = 'app_list_strings.'.$language;
  635. // Check for cached value
  636. $cache_entry = sugar_cache_retrieve($cache_key);
  637. if(!empty($cache_entry))
  638. {
  639. return $cache_entry;
  640. }
  641. $default_language = $sugar_config['default_language'];
  642. $temp_app_list_strings = $app_list_strings;
  643. $language_used = $language;
  644. include("include/language/en_us.lang.php");
  645. $en_app_list_strings = array();
  646. if($language_used != $default_language){
  647. require("include/language/$default_language.lang.php");
  648. if(file_exists("include/language/$default_language.lang.override.php")) {
  649. include("include/language/$default_language.lang.override.php");
  650. }
  651. if(file_exists("include/language/$default_language.lang.php.override")) {
  652. include("include/language/$default_language.lang.php.override");
  653. }
  654. $en_app_list_strings = $app_list_strings;
  655. }
  656. include("include/language/$language.lang.php");
  657. if(file_exists("include/language/$language.lang.override.php")) {
  658. include("include/language/$language.lang.override.php");
  659. }
  660. if(file_exists("include/language/$language.lang.php.override")) {
  661. include("include/language/$language.lang.php.override");
  662. }
  663. // cn: bug 6048 - merge en_us with requested language
  664. if (!empty($en_app_list_strings)) {
  665. $app_list_strings = sugarArrayMerge($en_app_list_strings, $app_list_strings);
  666. }
  667. if (file_exists("custom/application/Ext/Language/en_us.lang.ext.php")){
  668. $app_list_strings = _mergeCustomAppListStrings("custom/application/Ext/Language/en_us.lang.ext.php" , $app_list_strings) ;
  669. }
  670. if($language_used != $default_language){
  671. if(file_exists("custom/application/Ext/Language/$default_language.lang.ext.php")) {
  672. $app_list_strings = _mergeCustomAppListStrings("custom/application/Ext/Language/$default_language.lang.ext.php" , $app_list_strings);
  673. $GLOBALS['log']->info("Found extended language file: $default_language.lang.ext.php");
  674. }
  675. if(file_exists("custom/include/language/$default_language.lang.php")) {
  676. include("custom/include/language/$default_language.lang.php");
  677. $GLOBALS['log']->info("Found custom language file: $default_language.lang.php");
  678. }
  679. }
  680. if(file_exists("custom/application/Ext/Language/$language.lang.ext.php")) {
  681. $app_list_strings = _mergeCustomAppListStrings("custom/application/Ext/Language/$language.lang.ext.php" , $app_list_strings);
  682. $GLOBALS['log']->info("Found extended language file: $language.lang.ext.php");
  683. }
  684. if(file_exists("custom/include/language/$language.lang.php")) {
  685. include("custom/include/language/$language.lang.php");
  686. $GLOBALS['log']->info("Found custom language file: $language.lang.php");
  687. }
  688. if(!isset($app_list_strings)) {
  689. $GLOBALS['log']->warn("Unable to find the application language file for language: ".$language);
  690. $language_used = $default_language;
  691. $app_list_strings = $en_app_list_strings;
  692. }
  693. if(!isset($app_list_strings)) {
  694. $GLOBALS['log']->fatal("Unable to load the application language file for the selected language($language) or the default language($default_language)");
  695. return null;
  696. }
  697. $return_value = $app_list_strings;
  698. $app_list_strings = $temp_app_list_strings;
  699. sugar_cache_put($cache_key, $return_value);
  700. return $return_value;
  701. }
  702. /**
  703. * The dropdown items in custom language files is $app_list_strings['$key']['$second_key'] = $value not
  704. * $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.
  705. * @param file string the language that you want include,
  706. * @param app_list_strings array the golbal strings
  707. * @return array
  708. */
  709. //jchi 25347
  710. function _mergeCustomAppListStrings($file , $app_list_strings){
  711. $app_list_strings_original = $app_list_strings;
  712. unset($app_list_strings);
  713. include($file);
  714. if(!isset($app_list_strings) || !is_array($app_list_strings)){
  715. return $app_list_strings_original;
  716. }
  717. //Bug 25347: We should not merge custom dropdown fields unless they relate to parent fields or the module list.
  718. foreach($app_list_strings as $key=>$value)
  719. {
  720. $exemptDropdowns = array("moduleList", "parent_type_display", "record_type_display", "record_type_display_notes");
  721. if (!in_array($key, $exemptDropdowns) && array_key_exists($key, $app_list_strings_original))
  722. {
  723. unset($app_list_strings_original["$key"]);
  724. }
  725. }
  726. $app_list_strings = sugarArrayMergeRecursive($app_list_strings_original , $app_list_strings);
  727. return $app_list_strings;
  728. }
  729. /** This function retrieves an application language file and returns the array of strings included.
  730. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  731. * All Rights Reserved.
  732. * Contributor(s): ______________________________________..
  733. * If you are using the current language, do not call this function unless you are loading it for the first time */
  734. function return_application_language($language) {
  735. global $app_strings, $sugar_config;
  736. $cache_key = 'app_strings.'.$language;
  737. // Check for cached value
  738. $cache_entry = sugar_cache_retrieve($cache_key);
  739. if(!empty($cache_entry))
  740. {
  741. return $cache_entry;
  742. }
  743. $temp_app_strings = $app_strings;
  744. $language_used = $language;
  745. $default_language = $sugar_config['default_language'];
  746. // cn: bug 6048 - merge en_us with requested language
  747. include("include/language/en_us.lang.php");
  748. $en_app_strings = array();
  749. if($language_used != $default_language)
  750. $en_app_strings = $app_strings;
  751. if(!empty($language)) {
  752. include("include/language/$language.lang.php");
  753. }
  754. if(file_exists("include/language/$language.lang.override.php")) {
  755. include("include/language/$language.lang.override.php");
  756. }
  757. if(file_exists("include/language/$language.lang.php.override")) {
  758. include("include/language/$language.lang.php.override");
  759. }
  760. if(file_exists("custom/application/Ext/Language/$language.lang.ext.php")) {
  761. include("custom/application/Ext/Language/$language.lang.ext.php");
  762. $GLOBALS['log']->info("Found extended language file: $language.lang.ext.php");
  763. }
  764. if(file_exists("custom/include/language/$language.lang.php")) {
  765. include("custom/include/language/$language.lang.php");
  766. $GLOBALS['log']->info("Found custom language file: $language.lang.php");
  767. }
  768. if(!isset($app_strings)) {
  769. $GLOBALS['log']->warn("Unable to find the application language file for language: ".$language);
  770. require("include/language/$default_language.lang.php");
  771. if(file_exists("include/language/$default_language.lang.override.php")) {
  772. include("include/language/$default_language.lang.override.php");
  773. }
  774. if(file_exists("include/language/$default_language.lang.php.override")) {
  775. include("include/language/$default_language.lang.php.override");
  776. }
  777. if(file_exists("custom/application/Ext/Language/$default_language.lang.ext.php")) {
  778. include("custom/application/Ext/Language/$default_language.lang.ext.php");
  779. $GLOBALS['log']->info("Found extended language file: $default_language.lang.ext.php");
  780. }
  781. $language_used = $default_language;
  782. }
  783. if(!isset($app_strings)) {
  784. $GLOBALS['log']->fatal("Unable to load the application language file for the selected language($language) or the default language($default_language)");
  785. return null;
  786. }
  787. // cn: bug 6048 - merge en_us with requested language
  788. $app_strings = sugarArrayMerge($en_app_strings, $app_strings);
  789. // If we are in debug mode for translating, turn on the prefix now!
  790. if($sugar_config['translation_string_prefix']) {
  791. foreach($app_strings as $entry_key=>$entry_value) {
  792. $app_strings[$entry_key] = $language_used.' '.$entry_value;
  793. }
  794. }
  795. if(isset($_SESSION['show_deleted'])) {
  796. $app_strings['LBL_DELETE_BUTTON'] = $app_strings['LBL_UNDELETE_BUTTON'];
  797. $app_strings['LBL_DELETE_BUTTON_LABEL'] = $app_strings['LBL_UNDELETE_BUTTON_LABEL'];
  798. $app_strings['LBL_DELETE_BUTTON_TITLE'] = $app_strings['LBL_UNDELETE_BUTTON_TITLE'];
  799. $app_strings['LBL_DELETE'] = $app_strings['LBL_UNDELETE'];
  800. }
  801. $app_strings['LBL_ALT_HOT_KEY'] = get_alt_hot_key();
  802. $return_value = $app_strings;
  803. $app_strings = $temp_app_strings;
  804. sugar_cache_put($cache_key, $return_value);
  805. return $return_value;
  806. }
  807. /** This function retrieves a module's language file and returns the array of strings included.
  808. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  809. * All Rights Reserved.
  810. * Contributor(s): ______________________________________..
  811. * If you are in the current module, do not call this function unless you are loading it for the first time */
  812. function return_module_language($language, $module, $refresh=false) {
  813. global $mod_strings;
  814. global $sugar_config;
  815. global $currentModule;
  816. // Jenny - Bug 8119: Need to check if $module is not empty
  817. if (empty($module)) {
  818. $stack = debug_backtrace();
  819. $GLOBALS['log']->warn("Variable module is not in return_module_language ". var_export($stack, true));
  820. return array();
  821. }
  822. // Store the current mod strings for later
  823. $temp_mod_strings = $mod_strings;
  824. $loaded_mod_strings = array();
  825. $language_used = $language;
  826. $default_language = $sugar_config['default_language'];
  827. if(empty($language)) {
  828. $language = $default_language;
  829. }
  830. // Bug 21559 - So we can get all the strings defined in the template, refresh
  831. // the vardefs file if the cached language file doesn't exist.
  832. if(!file_exists($GLOBALS['sugar_config']['cache_dir'].'modules/'. $module . '/language/'.$language.'.lang.php')
  833. && !empty($GLOBALS['beanList'][$module])){
  834. $object = $GLOBALS['beanList'][$module];
  835. if ($object == 'aCase')
  836. $object = 'Case';
  837. VardefManager::refreshVardefs($module,$object);
  838. }
  839. $loaded_mod_strings = LanguageManager::loadModuleLanguage($module, $language,$refresh);
  840. // cn: bug 6048 - merge en_us with requested language
  841. if($language != $sugar_config['default_language'])
  842. $loaded_mod_strings = sugarArrayMerge(
  843. LanguageManager::loadModuleLanguage($module, $sugar_config['default_language'],$refresh),
  844. $loaded_mod_strings
  845. );
  846. // If we are in debug mode for translating, turn on the prefix now!
  847. if($sugar_config['translation_string_prefix']) {
  848. foreach($loaded_mod_strings as $entry_key=>$entry_value) {
  849. $loaded_mod_strings[$entry_key] = $language_used.' '.$entry_value;
  850. }
  851. }
  852. $return_value = $loaded_mod_strings;
  853. if(!isset($mod_strings)){
  854. $mod_strings = $return_value;
  855. }
  856. else
  857. $mod_strings = $temp_mod_strings;
  858. return $return_value;
  859. }
  860. /** This function retrieves an application language file and returns the array of strings included in the $mod_list_strings var.
  861. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  862. * All Rights Reserved.
  863. * Contributor(s): ______________________________________..
  864. * If you are using the current language, do not call this function unless you are loading it for the first time */
  865. function return_mod_list_strings_language($language,$module) {
  866. global $mod_list_strings;
  867. global $sugar_config;
  868. global $currentModule;
  869. $cache_key = "mod_list_str_lang.".$language.$module;
  870. // Check for cached value
  871. $cache_entry = sugar_cache_retrieve($cache_key);
  872. if(!empty($cache_entry))
  873. {
  874. return $cache_entry;
  875. }
  876. $language_used = $language;
  877. $temp_mod_list_strings = $mod_list_strings;
  878. $default_language = $sugar_config['default_language'];
  879. if($currentModule == $module && isset($mod_list_strings) && $mod_list_strings != null) {
  880. return $mod_list_strings;
  881. }
  882. // cn: bug 6351 - include en_us if file langpack not available
  883. // cn: bug 6048 - merge en_us with requested language
  884. include("modules/$module/language/en_us.lang.php");
  885. $en_mod_list_strings = array();
  886. if($language_used != $default_language)
  887. $en_mod_list_strings = $mod_list_strings;
  888. if(file_exists("modules/$module/language/$language.lang.php")) {
  889. include("modules/$module/language/$language.lang.php");
  890. }
  891. if(file_exists("modules/$module/language/$language.lang.override.php")){
  892. include("modules/$module/language/$language.lang.override.php");
  893. }
  894. if(file_exists("modules/$module/language/$language.lang.php.override")){
  895. echo 'Please Change:<br>' . "modules/$module/language/$language.lang.php.override" . '<br>to<br>' . 'Please Change:<br>' . "modules/$module/language/$language.lang.override.php";
  896. include("modules/$module/language/$language.lang.php.override");
  897. }
  898. // cn: bug 6048 - merge en_us with requested language
  899. $mod_list_strings = sugarArrayMerge($en_mod_list_strings, $mod_list_strings);
  900. // if we still don't have a language pack, then log an error
  901. if(!isset($mod_list_strings)) {
  902. $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})");
  903. return null;
  904. }
  905. $return_value = $mod_list_strings;
  906. $mod_list_strings = $temp_mod_list_strings;
  907. sugar_cache_put($cache_key, $return_value);
  908. return $return_value;
  909. }
  910. /** This function retrieves a theme's language file and returns the array of strings included.
  911. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  912. * All Rights Reserved.
  913. * Contributor(s): ______________________________________..
  914. */
  915. function return_theme_language($language, $theme)
  916. {
  917. global $mod_strings, $sugar_config, $currentModule;
  918. $language_used = $language;
  919. $default_language = $sugar_config['default_language'];
  920. include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php");
  921. if(file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php")){
  922. include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php");
  923. }
  924. if(file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override")){
  925. 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";
  926. include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override");
  927. }
  928. if(!isset($theme_strings))
  929. {
  930. $GLOBALS['log']->warn("Unable to find the theme file for language: ".$language." and theme: ".$theme);
  931. require(SugarThemeRegistry::get($theme)->getFilePath()."/language/$default_language.lang.php");
  932. $language_used = $default_language;
  933. }
  934. if(!isset($theme_strings))
  935. {
  936. $GLOBALS['log']->fatal("Unable to load the theme($theme) language file for the selected language($language) or the default language($default_language)");
  937. return null;
  938. }
  939. // If we are in debug mode for translating, turn on the prefix now!
  940. if($sugar_config['translation_string_prefix'])
  941. {
  942. foreach($theme_strings as $entry_key=>$entry_value)
  943. {
  944. $theme_strings[$entry_key] = $language_used.' '.$entry_value;
  945. }
  946. }
  947. return $theme_strings;
  948. }
  949. /** If the session variable is defined and is not equal to "" then return it. Otherwise, return the default value.
  950. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  951. * All Rights Reserved.
  952. * Contributor(s): ______________________________________..
  953. */
  954. function return_session_value_or_default($varname, $default)
  955. {
  956. if(isset($_SESSION[$varname]) && $_SESSION[$varname] != "")
  957. {
  958. return $_SESSION[$varname];
  959. }
  960. return $default;
  961. }
  962. /**
  963. * Creates an array of where restrictions. These are used to construct a where SQL statement on the query
  964. * 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.
  965. * @param &$where_clauses - The array to append the clause to
  966. * @param $variable_name - The name of the variable to look for an add to the where clause if found
  967. * @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.
  968. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  969. * All Rights Reserved.
  970. * Contributor(s): ______________________________________..
  971. */
  972. function append_where_clause(&$where_clauses, $variable_name, $SQL_name = null)
  973. {
  974. if($SQL_name == null)
  975. {
  976. $SQL_name = $variable_name;
  977. }
  978. if(isset($_REQUEST[$variable_name]) && $_REQUEST[$variable_name] != "")
  979. {
  980. array_push($where_clauses, "$SQL_name like '".$GLOBALS['db']->quote($_REQUEST[$variable_name])."%'");
  981. }
  982. }
  983. /**
  984. * Generate the appropriate SQL based on the where clauses.
  985. * @param $where_clauses - An Array of individual where clauses stored as strings
  986. * @returns string where_clause - The final SQL where clause to be executed.
  987. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  988. * All Rights Reserved.
  989. * Contributor(s): ______________________________________..
  990. */
  991. function generate_where_statement($where_clauses)
  992. {
  993. $where = "";
  994. foreach($where_clauses as $clause)
  995. {
  996. if($where != "")
  997. $where .= " and ";
  998. $where .= $clause;
  999. }
  1000. $GLOBALS['log']->info("Here is the where clause for the list view: $where");
  1001. return $where;
  1002. }
  1003. /**
  1004. * determines if a passed string matches the criteria for a Sugar GUID
  1005. * @param string $guid
  1006. * @return bool False on failure
  1007. */
  1008. function is_guid($guid) {
  1009. if(strlen($guid) != 36) {
  1010. return false;
  1011. }
  1012. if(preg_match("/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/i", $guid)) {
  1013. return true;
  1014. }
  1015. return true;;
  1016. }
  1017. /**
  1018. * A temporary method of generating GUIDs of the correct format for our DB.
  1019. * @return String contianing a GUID in the format: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
  1020. *
  1021. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1022. * All Rights Reserved.
  1023. * Contributor(s): ______________________________________..
  1024. */
  1025. function create_guid()
  1026. {
  1027. $microTime = microtime();
  1028. list($a_dec, $a_sec) = explode(" ", $microTime);
  1029. $dec_hex = dechex($a_dec* 1000000);
  1030. $sec_hex = dechex($a_sec);
  1031. ensure_length($dec_hex, 5);
  1032. ensure_length($sec_hex, 6);
  1033. $guid = "";
  1034. $guid .= $dec_hex;
  1035. $guid .= create_guid_section(3);
  1036. $guid .= '-';
  1037. $guid .= create_guid_section(4);
  1038. $guid .= '-';
  1039. $guid .= create_guid_section(4);
  1040. $guid .= '-';
  1041. $guid .= create_guid_section(4);
  1042. $guid .= '-';
  1043. $guid .= $sec_hex;
  1044. $guid .= create_guid_section(6);
  1045. return $guid;
  1046. }
  1047. function create_guid_section($characters)
  1048. {
  1049. $return = "";
  1050. for($i=0; $i<$characters; $i++)
  1051. {
  1052. $return .= dechex(mt_rand(0,15));
  1053. }
  1054. return $return;
  1055. }
  1056. function ensure_length(&$string, $length)
  1057. {
  1058. $strlen = strlen($string);
  1059. if($strlen < $length)
  1060. {
  1061. $string = str_pad($string,$length,"0");
  1062. }
  1063. else if($strlen > $length)
  1064. {
  1065. $string = substr($string, 0, $length);
  1066. }
  1067. }
  1068. function microtime_diff($a, $b) {
  1069. list($a_dec, $a_sec) = explode(" ", $a);
  1070. list($b_dec, $b_sec) = explode(" ", $b);
  1071. return $b_sec - $a_sec + $b_dec - $a_dec;
  1072. }
  1073. // check if Studio is displayed.
  1074. function displayStudioForCurrentUser(){
  1075. return true;
  1076. }
  1077. function displayWorkflowForCurrentUser(){
  1078. $_SESSION['display_workflow_for_user'] = false;
  1079. return false;
  1080. }
  1081. // return an array with all modules where the user is an admin.
  1082. function get_admin_modules_for_user($user) {
  1083. global $beanList;
  1084. $admin_modules = array();
  1085. return ($admin_modules);
  1086. }
  1087. function get_workflow_admin_modules_for_user($user){
  1088. if (isset($_SESSION['get_workflow_admin_modules_for_user'])) {
  1089. return $_SESSION['get_workflow_admin_modules_for_user'];
  1090. }
  1091. global $moduleList;
  1092. $workflow_mod_list = array();
  1093. foreach($moduleList as $module){
  1094. $workflow_mod_list[$module] = $module;
  1095. }
  1096. // This list is taken from teh previous version of workflow_utils.php
  1097. $workflow_mod_list['Tasks'] = "Tasks";
  1098. $workflow_mod_list['Calls'] = "Calls";
  1099. $workflow_mod_list['Meetings'] = "Meetings";
  1100. $workflow_mod_list['Notes'] = "Notes";
  1101. $workflow_mod_list['ProjectTask'] = "Project Tasks";
  1102. $workflow_mod_list['Leads'] = "Leads";
  1103. $workflow_mod_list['Opportunities'] = "Opportunities";
  1104. // End of list
  1105. $workflow_admin_modules = array();
  1106. if(empty($user)) {
  1107. return $workflow_admin_modules;
  1108. }
  1109. $actions = ACLAction::getUserActions($user->id);
  1110. //check for ForecastSchedule because it doesn't exist in $workflow_mod_list
  1111. if ($actions['ForecastSchedule']['module']['admin']['aclaccess']==ACL_ALLOW_DEV || $actions['ForecastSchedule']['module']['admin']['aclaccess']==ACL_ALLOW_ADMIN_DEV) {
  1112. $workflow_admin_modules['Forecasts'] = 'Forecasts';
  1113. }
  1114. foreach ($workflow_mod_list as $key=>$val) {
  1115. if(!in_array($val, $workflow_admin_modules) && ($val!='iFrames' && $val!='Feeds' && $val!='Home' && $val!='Dashboard'
  1116. && $val!='Calendar' && $val!='Activities' && $val!='Reports') &&
  1117. (is_admin_for_module($user,$key))) {
  1118. $workflow_admin_modules[$key] = $val;
  1119. }
  1120. }
  1121. $_SESSION['get_workflow_admin_modules_for_user'] = $workflow_admin_modules;
  1122. return ($workflow_admin_modules);
  1123. }
  1124. // Check if user is admin for at least one module.
  1125. function is_admin_for_any_module($user) {
  1126. return false;
  1127. }
  1128. // Check if user is admin for a specific module.
  1129. function is_admin_for_module($user,$module) {
  1130. return false;
  1131. }
  1132. /**
  1133. * Check if user id belongs to a system admin.
  1134. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1135. * All Rights Reserved.
  1136. * Contributor(s): ______________________________________..
  1137. */
  1138. function is_admin($user) {
  1139. if(!empty($user) && ($user->is_admin == '1' || $user->is_admin === 'on')){
  1140. return true;
  1141. }
  1142. return false;
  1143. }
  1144. /**
  1145. * Return the display name for a theme if it exists.
  1146. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1147. * All Rights Reserved.
  1148. * Contributor(s): ______________________________________..
  1149. *
  1150. * @deprecated use SugarThemeRegistry::get($theme)->name instead
  1151. */
  1152. function get_theme_display($theme)
  1153. {
  1154. return SugarThemeRegistry::get($theme)->name;
  1155. }
  1156. /**
  1157. * Return an array of directory names.
  1158. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1159. * All Rights Reserved.
  1160. * Contributor(s): ______________________________________..
  1161. *
  1162. * @deprecated use SugarThemeRegistry::availableThemes() instead.
  1163. */
  1164. function get_themes()
  1165. {
  1166. return SugarThemeRegistry::availableThemes();
  1167. }
  1168. /**
  1169. * THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED; USE get_select_options_with_id()
  1170. * Create HTML to display select options in a dropdown list. To be used inside
  1171. * of a select statement in a form.
  1172. * param $option_list - the array of strings to that contains the option list
  1173. * param $selected - the string which contains the default value
  1174. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1175. * All Rights Reserved.
  1176. * Contributor(s): ______________________________________..
  1177. */
  1178. function get_select_options ($option_list, $selected) {
  1179. return get_select_options_with_id($option_list, $selected);
  1180. }
  1181. /**
  1182. * Create HTML to display select options in a dropdown list. To be used inside
  1183. * 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.
  1184. * param $option_list - the array of strings to that contains the option list
  1185. * param $selected - the string which contains the default value
  1186. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1187. * All Rights Reserved.
  1188. * Contributor(s): ______________________________________..
  1189. */
  1190. function get_select_options_with_id ($option_list, $selected_key) {
  1191. return get_select_options_with_id_separate_key($option_list, $option_list, $selected_key);
  1192. }
  1193. /**
  1194. * Create HTML to display select options in a dropdown list. To be used inside
  1195. * 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.
  1196. * param $label_list - the array of strings to that contains the option list
  1197. * param $key_list - the array of strings to that contains the values list
  1198. * param $selected - the string which contains the default value
  1199. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1200. * All Rights Reserved.
  1201. * Contributor(s): ______________________________________..
  1202. */
  1203. function get_select_options_with_id_separate_key ($label_list, $key_list, $selected_key) {
  1204. global $app_strings;
  1205. $select_options = "";
  1206. //for setting null selection values to human readable --None--
  1207. $pattern = "/'0?'></";
  1208. $replacement = "''>".$app_strings['LBL_NONE']."<";
  1209. if (empty($key_list)) $key_list = array();
  1210. //create the type dropdown domain and set the selected value if $opp value already exists
  1211. foreach ($key_list as $option_key=>$option_value) {
  1212. $selected_string = '';
  1213. // the system is evaluating $selected_key == 0 || '' to true. Be very careful when changing this. Test all cases.
  1214. // The bug was only happening with one of the users in the drop down. It was being replaced by none.
  1215. if (($option_key != '' && $selected_key == $option_key) || ($selected_key == '' && $option_key == '') || (is_array($selected_key) && in_array($option_key, $selected_key)))
  1216. {
  1217. $selected_string = 'selected ';
  1218. }
  1219. $html_value = $option_key;
  1220. $select_options .= "\n<OPTION ".$selected_string."value='$html_value'>$label_list[$option_key]</OPTION>";
  1221. }
  1222. $select_options = preg_replace($pattern, $replacement, $select_options);
  1223. return $select_options;
  1224. }
  1225. /**
  1226. * Call this method instead of die().
  1227. * Then we call the die method with the error message that is passed in.
  1228. */
  1229. function sugar_die($error_message)
  1230. {
  1231. global $focus;
  1232. sugar_cleanup();
  1233. die($error_message);
  1234. }
  1235. /**
  1236. * Create javascript to clear values of all elements in a form.
  1237. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1238. * All Rights Reserved.
  1239. * Contributor(s): ______________________________________..
  1240. */
  1241. function get_clear_form_js () {
  1242. $the_script = <<<EOQ
  1243. <script type="text/javascript" language="JavaScript">
  1244. function clear_form(form) {
  1245. var newLoc = 'index.php?action=' + form.action.value + '&module=' + form.module.value + '&query=true&clear_query=true';
  1246. if(typeof(form.advanced) != 'undefined'){
  1247. newLoc += '&advanced=' + form.advanced.value;
  1248. }
  1249. document.location.href= newLoc;
  1250. }
  1251. </script>
  1252. EOQ;
  1253. return $the_script;
  1254. }
  1255. /**
  1256. * Create javascript to set the cursor focus to specific field in a form
  1257. * when the screen is rendered. The field name is currently hardcoded into the
  1258. * the function.
  1259. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1260. * All Rights Reserved.
  1261. * Contributor(s): ______________________________________..
  1262. */
  1263. function get_set_focus_js () {
  1264. //TODO Clint 5/20 - Make this function more generic so that it can take in the target form and field names as variables
  1265. $the_script = <<<EOQ
  1266. <script type="text/javascript" language="JavaScript">
  1267. <!-- Begin
  1268. function set_focus() {
  1269. if (document.forms.length > 0) {
  1270. for (i = 0; i < document.forms.length; i++) {
  1271. for (j = 0; j < document.forms[i].elements.length; j++) {
  1272. var field = document.forms[i].elements[j];
  1273. if ((field.type == "text" || field.type == "textarea" || field.type == "password") &&
  1274. !field.disabled && (field.name == "first_name" || field.name == "name" || field.name == "user_name" || field.name=="document_name")) {
  1275. field.focus();
  1276. if (field.type == "text") {
  1277. field.select();
  1278. }
  1279. break;
  1280. }
  1281. }
  1282. }
  1283. }
  1284. }
  1285. // End -->
  1286. </script>
  1287. EOQ;
  1288. return $the_script;
  1289. }
  1290. /**
  1291. * Very cool algorithm for sorting multi-dimensional arrays. Found at http://us2.php.net/manual/en/function.array-multisort.php
  1292. * Syntax: $new_array = array_csort($array [, 'col1' [, SORT_FLAG [, SORT_FLAG]]]...);
  1293. * Explanation: $array is the array you want to sort, 'col1' is the name of the column
  1294. * you want to sort, SORT_FLAGS are : SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
  1295. * you can repeat the 'col',FLAG,FLAG, as often you want, the highest prioritiy is given to
  1296. * the first - so the array is sorted by the last given column first, then the one before ...
  1297. * Example: $array = array_csort($array,'town','age',SORT_DESC,'name');
  1298. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1299. * All Rights Reserved.
  1300. * Contributor(s): ______________________________________..
  1301. */
  1302. function array_csort() {
  1303. $args = func_get_args();
  1304. $marray = array_shift($args);
  1305. $i = 0;
  1306. $msortline = "return(array_multisort(";
  1307. foreach ($args as $arg) {
  1308. $i++;
  1309. if (is_string($arg)) {
  1310. foreach ($marray as $row) {
  1311. $sortarr[$i][] = $row[$arg];
  1312. }
  1313. } else {
  1314. $sortarr[$i] = $arg;
  1315. }
  1316. $msortline .= "\$sortarr[".$i."],";
  1317. }
  1318. $msortline .= "\$marray));";
  1319. eval($msortline);
  1320. return $marray;
  1321. }
  1322. /**
  1323. * Converts localized date format string to jscalendar format
  1324. * Example: $array = array_csort($array,'town','age',SORT_DESC,'name');
  1325. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
  1326. * All Rights Reserved.
  1327. * Contributor(s): ______________________________________..
  1328. */
  1329. function parse_calendardate($local_format) {
  1330. preg_match("/\(?([^-]{1})[^-]*-([^-]{1})[^-]*-([^-]{1})[^-]*\)/", $local_format, $matches);
  1331. $calendar_format = "%" . $matches[1] . "-%" . $matches[2] . "-%" . $matches[3];
  1332. return str_replace(array("y", "�", "a", "j"), array("Y", "Y", "Y", "d"), $calendar_format);
  1333. }
  1334. function translate($string, $mod='', $selectedValue=''){
  1335. //$test_start = microtime();
  1336. //static $mod_strings_results = array();
  1337. if(!empty($mod)){
  1338. global $current_language;
  1339. $mod_strings = return_module_language($current_language, $mod);
  1340. }else{
  1341. global $mod_strings;
  1342. }
  1343. $returnValue = '';
  1344. global $app_strings, $app_list_strings;
  1345. if(isset($mod_strings[$string]))
  1346. $returnValue = $mod_strings[$string];
  1347. else if(isset($app_strings[$string]))
  1348. $returnValue = $app_strings[$string];
  1349. else if(isset($app_list_strings[$string]))
  1350. $returnValue = $app_list_strings[$string];
  1351. else if(isset($app_list_strings['moduleList']) && isset($app_list_strings['moduleList'][$string]))
  1352. $returnValue = $app_list_strings['moduleList'][$string];
  1353. //$test_end = microtime();
  1354. //
  1355. // $mod_strings_results[$mod] = microtime_diff($test_start,$test_end);
  1356. //
  1357. // echo("translate results:");
  1358. // $total_time = 0;
  1359. // $total_strings = 0;
  1360. // foreach($mod_strings_results as $key=>$value)
  1361. // {
  1362. // echo("Module $key \t\t time $value \t\t<br>");
  1363. // $total_time += $value;
  1364. // }
  1365. //
  1366. // echo("Total time: $total_time<br>");
  1367. if(empty($returnValue)){
  1368. return $string;
  1369. }
  1370. if(is_array($returnValue) && ! empty($selectedValue) && isset($returnValue[$selectedValue]) ){
  1371. return $returnValue[$selectedValue];
  1372. }
  1373. return $returnValue;
  1374. }
  1375. function unTranslateNum($num) {
  1376. static $dec_sep;
  1377. static $num_grp_sep;
  1378. global $current_user, $sugar_config;
  1379. if($dec_sep == null) {
  1380. $user_dec_sep = $current_user->getPreference('dec_sep');
  1381. $dec_sep = (empty($user_dec_sep) ? $sugar_config['default_decimal_seperator'] : $user_dec_sep);
  1382. }
  1383. if($num_grp_sep == null) {
  1384. $user_num_grp_sep = $current_user->getPreference('num_grp_sep');
  1385. $num_grp_sep = (empty($user_num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $user_num_grp_sep);
  1386. }
  1387. $num = preg_replace("'" . preg_quote($num_grp_sep) . "'", '', $num);
  1388. $num = preg_replace("'" . preg_quote($dec_sep) . "'", '.', $num);
  1389. return $num;
  1390. }
  1391. function add_http($url) {
  1392. if(!eregi("://", $url)) {
  1393. $scheme = "http";
  1394. if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
  1395. $scheme = 'https';
  1396. }
  1397. return "{$scheme}://{$url}";
  1398. }
  1399. return $url;
  1400. }
  1401. /**
  1402. * returns a default array of XSS tags to clean
  1403. * @return array
  1404. */
  1405. function getDefaultXssTags() {
  1406. $tmp = array(
  1407. "applet" => "applet",
  1408. "base" => "base",
  1409. "embed" => "embed",
  1410. "form" => "form",
  1411. "frame" => "frame",
  1412. "frameset" => "frameset",
  1413. "iframe" => "iframe",
  1414. "import" => "\?import",
  1415. "layer" => "layer",
  1416. "link" => "link",
  1417. "object" => "object",
  1418. "script" => "script",
  1419. "xmp" => "xmp",
  1420. );
  1421. $ret = base64_encode(serialize($tmp));
  1422. return $ret;
  1423. }
  1424. /**
  1425. * Detects typical XSS attack patterns
  1426. * @param string str String to search for XSS attack vectors
  1427. * @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images.
  1428. * @return array Array of matches, empty on clean string
  1429. */
  1430. function clean_xss($str, $cleanImg=true) {
  1431. global $sugar_config;
  1432. if(empty($sugar_config['email_xss']))
  1433. $sugar_config['email_xss'] = getDefaultXssTags();
  1434. $arr = unserialize(base64_decode($sugar_config['email_xss']));
  1435. $regex = '';
  1436. foreach($arr as $v) {
  1437. if(!empty($regex)) {
  1438. $regex .= "|";
  1439. }
  1440. $regex .= $v;
  1441. }
  1442. $tag_regex = "#<({$regex})[^>]*>?#sim";
  1443. // cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.)
  1444. $jsEvents = "onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|";
  1445. $jsEvents .= "onmouseup|onmouseover|onmousedown|onmouseenter|onmouseleave|onmousemove|onload|onchange|";
  1446. $jsEvents .= "onreset|onselect|onsubmit|onkeydown|onkeypress|onkeyup|onabort|onerror";
  1447. $attribute_regex = "#<[^/>][^>]+({$jsEvents}|data\w+)[^=>]*=[^>]*>#sim";
  1448. $javascript_regex = '@<[^/>][^>]+(expression|j\W*a\W*v\W*a|v\W*b\W*s\W*c\W*r|&#|/\*|\*/)[^>]*>@sim';
  1449. $imgsrc_regex = '#<[^>]+src[^=]*=([^>]*?http://[^>]*)>#sim';
  1450. $css_url = "#url\(.*\.\w+\)#";
  1451. $str = str_replace("\t", "", $str);
  1452. $matches = array_merge(
  1453. xss_check_pattern($tag_regex, $str),
  1454. xss_check_pattern($javascript_regex, $str),
  1455. xss_check_pattern($attribute_regex, $str)
  1456. );
  1457. if($cleanImg) {
  1458. $matches = array_merge($matches,
  1459. xss_check_pattern($imgsrc_regex, $str)
  1460. );
  1461. }
  1462. // cn: bug 13498 - custom white-list of allowed domains that vet remote images
  1463. preg_match_all($css_url, $str, $cssUrlMatches, PREG_PATTERN_ORDER);
  1464. if(isset($sugar_config['security_trusted_domains']) && !empty($sugar_config['security_trusted_domains']) && is_array($sugar_config['security_trusted_domains'])) {
  1465. if(is_array($cssUrlMatches) && count($cssUrlMatches) > 0) {
  1466. // normalize whitelist
  1467. foreach($sugar_config['security_trusted_domains'] as $k => $v) {
  1468. $sugar_config['security_trusted_domains'][$k] = strtolower($v);
  1469. }
  1470. foreach($cssUrlMatches[0] as $match) {
  1471. $domain = strtolower(substr(strstr($match, "://"), 3));
  1472. $baseUrl = substr($domain, 0, strpos($domain, "/"));
  1473. if(!in_array($baseUrl, $sugar_config['security_trusted_domains'])) {
  1474. $matches[] = $match;
  1475. }
  1476. }
  1477. }
  1478. } else {
  1479. $matches = array_merge($matches, $cssUrlMatches[0]);
  1480. }
  1481. return $matches;
  1482. }
  1483. /**
  1484. * Helper function used by clean_xss() to parse for known-bad vectors
  1485. * @param string pattern Regex pattern to use
  1486. * @param string str String to parse for badness
  1487. * @return array
  1488. */
  1489. function xss_check_pattern($pattern, $str) {
  1490. preg_match_all($pattern, $str, $matches, PREG_PATTERN_ORDER);
  1491. return $matches[1];
  1492. }
  1493. // Designed to take a string passed in the URL as a parameter and clean all "bad" data from it
  1494. // The second argument is a string, "filter," which corresponds to a regular expression
  1495. function clean_string($str, $filter = "STANDARD") {
  1496. global $sugar_config;
  1497. $filters = Array(
  1498. "STANDARD" => "#[^A-Z0-9\-_\.\@]#i",
  1499. "STANDARDSPACE" => "#[^A-Z0-9\-_\.\@\ ]#i",
  1500. "FILE" => "#[^A-Z0-9\-_\.]#i",
  1501. "NUMBER" => "#[^0-9\-]#i",
  1502. "SQL_COLUMN_LIST" => "#[^A-Z0-9,_\.]#i",
  1503. "PATH_NO_URL" => "#://#i",
  1504. "SAFED_GET" => "#[^A-Z0-9\@\=\&\?\.\/\-_~]#i", /* range of allowed characters in a GET string */
  1505. "UNIFIED_SEARCH" => "#[\\x00]#", /* cn: bug 3356 & 9236 - MBCS search strings */
  1506. "AUTO_INCREMENT" => "#[^0-9\-,\ ]#i",
  1507. "ALPHANUM" => "#[^A-Z0-9\-]#i",
  1508. );
  1509. if (preg_match($filters[$filter], $str)) {
  1510. if (isset($GLOBALS['log']) && is_object($GLOBALS['log'])) {
  1511. $GLOBALS['log']->fatal("SECURITY: bad data passed in; string: {$str}");
  1512. }
  1513. die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>");
  1514. }
  1515. else {
  1516. return $str;
  1517. }
  1518. }
  1519. function clean_special_arguments() {
  1520. if(isset($_SERVER['PHP_SELF'])) {
  1521. if (!empty($_SERVER['PHP_SELF'])) clean_string($_SERVER['PHP_SELF'], 'SAFED_GET');
  1522. }
  1523. if (!empty($_REQUEST) && !empty($_REQUEST['login_theme'])) clean_string($_REQUEST['login_theme'], "STANDARD");
  1524. if (!empty($_REQUEST) && !empty($_REQUEST['ck_login_theme_20'])) clean_string($_REQUEST['ck_login_theme_20'], "STANDARD");
  1525. if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_theme'])) clean_string($_SESSION['authenticated_user_theme'], "STANDARD");
  1526. if (!empty($_REQUEST) && !empty($_REQUEST['module_name'])) clean_string($_REQUEST['module_name'], "STANDARD");
  1527. if (!empty($_REQUEST) && !empty($_REQUEST['module'])) clean_string($_REQUEST['module'], "STANDARD");
  1528. if (!empty($_POST) && !empty($_POST['parent_type'])) clean_string($_POST['parent_type'], "STANDARD");
  1529. if (!empty($_REQUEST) && !empty($_REQUEST['mod_lang'])) clean_string($_REQUEST['mod_lang'], "STANDARD");
  1530. if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_language'])) clean_string($_SESSION['authenticated_user_language'], "STANDARD");
  1531. if (!empty($_SESSION) && !empty($_SESSION['dyn_layout_file'])) clean_string($_SESSION['dyn_layout_file'], "PATH_NO_URL");
  1532. if (!empty($_GET) && !empty($_GET['from'])) clean_string($_GET['from']);
  1533. if (!empty($_GET) && !empty($_GET['gmto'])) clean_string($_GET['gmto'], "NUMBER");
  1534. if (!empty($_GET) && !empty($_GET['case_number'])) clean_string($_GET['case_number'], "AUTO_INCREMENT");
  1535. if (!empty($_GET) && !empty($_GET['bug_number'])) clean_string($_GET['bug_number'], "AUTO_INCREMENT");
  1536. if (!empty($_GET) && !empty($_GET['quote_num'])) clean_string($_GET['quote_num'], "AUTO_INCREMENT");
  1537. clean_superglobals('stamp', 'ALPHANUM'); // for vcr controls
  1538. clean_superglobals('offset', 'ALPHANUM');
  1539. clean_superglobals('return_action');
  1540. clean_superglobals('return_module');
  1541. return TRUE;
  1542. }
  1543. /**
  1544. * cleans the given key in superglobals $_GET, $_POST, $_REQUEST
  1545. */
  1546. function clean_superglobals($key, $filter = 'STANDARD') {
  1547. if(isset($_GET[$key])) clean_string($_GET[$key], $filter);
  1548. if(isset($_POST[$key])) clean_string($_POST[$key], $filter);
  1549. if(isset($_REQUEST[$key])) clean_string($_REQUEST[$key], $filter);
  1550. }
  1551. // Works in conjunction with clean_string() to defeat SQL injection, file inclusion attacks, and XSS
  1552. function clean_incoming_data() {
  1553. global $sugar_config;
  1554. if (get_magic_quotes_gpc() == 1) {
  1555. $req = array_map("preprocess_param", $_REQUEST);
  1556. $post = array_map("preprocess_param", $_POST);
  1557. $get = array_map("preprocess_param", $_GET);
  1558. } else {
  1559. $req = array_map("securexss", $_REQUEST);
  1560. $post = array_map("securexss", $_POST);
  1561. $get = array_map("securexss", $_GET);
  1562. }
  1563. // PHP cannot stomp out superglobals reliably
  1564. foreach($post as $k => $v) { $_POST[$k] = $v; }
  1565. foreach($get as $k => $v) { $_GET[$k] = $v; }
  1566. foreach($req as $k => $v) {
  1567. $_REQUEST[$k] = $v;
  1568. //ensure the keys are safe as well
  1569. securexsskey($k);
  1570. }
  1571. // Any additional variables that need to be cleaned should be added here
  1572. if (isset($_REQUEST['login_theme'])) clean_string($_REQUEST['login_theme']);
  1573. if (isset($_REQUEST['login_language'])) clean_string($_REQUEST['login_language']);
  1574. if (isset($_REQUEST['action'])) clean_string($_REQUEST['action']);
  1575. if (isset($_REQUEST['module'])) clean_string($_REQUEST['module']);
  1576. if (isset($_REQUEST['record'])) clean_string($_REQUEST['record'], 'STANDARDSPACE');
  1577. if (isset($_SESSION['authenticated_user_theme'])) clean_string($_SESSION['authenticated_user_theme']);
  1578. if (isset($_SESSION['authenticated_user_language'])) clean_string($_SESSION['authenticated_user_language']);
  1579. if (isset($_REQUEST['language'])) clean_string($_REQUEST['language']);
  1580. if (isset($sugar_config['default_theme'])) clean_string($sugar_config['default_theme']);
  1581. if (isset($_REQUEST['offset'])) clean_string($_REQUEST['offset']);
  1582. if (isset($_REQUEST['stamp'])) clean_string($_REQUEST['stamp']);
  1583. // Clean "offset" and "order_by" parameters in URL
  1584. foreach ($_GET as $key => $val) {
  1585. if (str_end($key, "_offset")) {
  1586. clean_string($_GET[$key], "ALPHANUM"); // keep this ALPHANUM for disable_count_query
  1587. }
  1588. elseif (str_end($key, "_ORDER_BY")) {
  1589. clean_string($_GET[$key], "SQL_COLUMN_LIST");
  1590. }
  1591. }
  1592. return 0;
  1593. }
  1594. // Returns TRUE if $str begins with $begin
  1595. function str_begin($str, $begin) {
  1596. return (substr($str, 0, strlen($begin)) == $begin);
  1597. }
  1598. // Returns TRUE if $str ends with $end
  1599. function str_end($str, $end) {
  1600. return (substr($str, strlen($str) - strlen($end)) == $end);
  1601. }
  1602. function securexss($value) {
  1603. if(is_array($value)){
  1604. $new = array();
  1605. foreach($value as $key=>$val){
  1606. $new[$key] = securexss($val);
  1607. }
  1608. return $new;
  1609. }
  1610. static $xss_cleanup= array('"' =>'&quot;', "'" => '&#039;' , '<' =>'&lt;' , '>'=>'&gt;');
  1611. $value = preg_replace(array('/javascript:/i', '/\0/'), array('java script:', ''), $value);
  1612. $value = preg_replace('/javascript:/i', 'java script:', $value);
  1613. return str_replace(array_keys($xss_cleanup), array_values($xss_cleanup), $value);
  1614. }
  1615. function securexsskey($value, $die=true){
  1616. global $sugar_config;
  1617. $matches = array();
  1618. preg_match("/[\'\"\<\>]/", $value, $matches);
  1619. if(!empty($matches)){
  1620. if($die){
  1621. die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>");
  1622. }else{
  1623. unset($_REQUEST[$value]);
  1624. unset($_POST[$value]);
  1625. unset($_GET[$value]);
  1626. }
  1627. }
  1628. }
  1629. function preprocess_param($value){
  1630. if(is_string($value)){
  1631. if(get_magic_quotes_gpc() == 1){
  1632. $value = stripslashes($value);
  1633. }
  1634. $value = securexss($value);
  1635. }
  1636. return $value;
  1637. }
  1638. function set_register_value($category, $name, $value){
  1639. return sugar_cache_put("{$category}:{$name}", $value);
  1640. }
  1641. function get_register_value($category,$name){
  1642. return sugar_cache_retrieve("{$category}:{$name}");
  1643. }
  1644. // this function cleans id's when being imported
  1645. function convert_id($string)
  1646. {
  1647. return preg_replace_callback( '|[^A-Za-z0-9\-]|',
  1648. create_function(
  1649. // single quotes are essential here,
  1650. // or alternative escape all $ as \$
  1651. '$matches',
  1652. 'return ord($matches[0]);'
  1653. ) ,$string);
  1654. }
  1655. /**
  1656. * @deprecated use SugarTheme::getImage()
  1657. */
  1658. function get_image($image,$other_attributes,$width="",$height=""){
  1659. static $cached_results = array();
  1660. if(!empty($cached_results[$image]))
  1661. {
  1662. return $cached_results[$image]."$other_attributes>";
  1663. }
  1664. global $png_support;
  1665. $rel_path = $image;
  1666. if(defined('TEMPLATE_URL'))$rel_path = str_replace(TEMPLATE_URL.'/', '', $image);
  1667. if ($png_support == false)
  1668. $ext = "gif";
  1669. else
  1670. $ext = "png";
  1671. $out = '';
  1672. if (file_exists('custom/'. $rel_path.'.'.$ext)){
  1673. $rel_path = 'custom/'. $rel_path;
  1674. }
  1675. if (file_exists($rel_path.'.'.$ext)){
  1676. $size=getimagesize($rel_path.'.'.$ext);
  1677. if ($width == "") { $width = $size[0];}
  1678. if ($height == "") { $height = $size[1];}
  1679. $path = $image. '.'.$ext ;
  1680. $out= "<img src='$path' width='".$width."' height='".$height."' $other_attributes>";
  1681. }else if(substr_count($rel_path,'themes') > 0){
  1682. $path = explode('/',$rel_path);
  1683. $path[1] = 'default';
  1684. $new_path = implode('/',$path);
  1685. if(file_exists('custom/' . $new_path .'.'.$ext)){
  1686. $new_path = 'custom/' . $new_path;
  1687. }
  1688. if (file_exists($new_path.'.'.$ext)){
  1689. $size = getimagesize($new_path.'.'.$ext);
  1690. if ($width == "") { $width = $size[0];}
  1691. if ($height == "") { $height = $size[1];}
  1692. $path = $new_path.'.'.$ext;
  1693. if(defined('TEMPLATE_URL'))$path = getWebPath($path);
  1694. $out= "<img src='$path' width='".$width."' height='".$height."' $other_attributes>";
  1695. }
  1696. }
  1697. // Cache everything but the other attributes....
  1698. $cached_results[$image] = "<img src='$path' width='".$width."' height='".$height."' ";
  1699. return $out;
  1700. }
  1701. /**
  1702. * @deprecated use SugarTheme::getImageURL()
  1703. */
  1704. function getImagePath($image_name)
  1705. {
  1706. return SugarThemeRegistry::current()->getImageURL($image_name);
  1707. }
  1708. function getWebPath($relative_path){
  1709. //if it has a :// then it isn't a relative path
  1710. if(substr_count($relative_path, '://') > 0) return $relative_path;
  1711. if(defined('TEMPLATE_URL'))$relative_path = SugarTemplateUtilities::getWebPath($relative_path);
  1712. return $relative_path;
  1713. }
  1714. function getJSPath($relative_path, $additional_attrs=''){
  1715. if(defined('TEMPLATE_URL'))$relative_path = SugarTemplateUtilities::getWebPath($relative_path);
  1716. if(empty($GLOBALS['sugar_config']['js_custom_version']))$GLOBALS['sugar_config']['js_custom_version'] = 1;
  1717. $js_version_key = isset($GLOBALS['js_version_key'])?$GLOBALS['js_version_key']:'';
  1718. $path = $relative_path . '?s=' . $js_version_key . '&c=' . $GLOBALS['sugar_config']['js_custom_version'] ;
  1719. if ( inDeveloperMode() ) $path .= '&developerMode='.mt_rand();
  1720. if(!empty($additonal_attrs)) $path .= '&' . $additional_attrs;
  1721. return $path;
  1722. }
  1723. function getSWFPath($relative_path, $additional_params=''){
  1724. $path = $relative_path;
  1725. if (!empty($additional_params)){
  1726. $path .= '?' . $additional_params;
  1727. }
  1728. if (defined('TEMPLATE_URL')){
  1729. $path = TEMPLATE_URL . '/' . $path;
  1730. }
  1731. return $path;
  1732. }
  1733. function getSQLDate($date_str)
  1734. {
  1735. if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/',$date_str,$match))
  1736. {
  1737. if ( strlen($match[2]) == 1)
  1738. {
  1739. $match[2] = "0".$match[2];
  1740. }
  1741. if ( strlen($match[1]) == 1)
  1742. {
  1743. $match[1] = "0".$match[1];
  1744. }
  1745. return "{$match[3]}-{$match[1]}-{$match[2]}";
  1746. }
  1747. else if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/',$date_str,$match))
  1748. {
  1749. if ( strlen($match[2]) == 1)
  1750. {
  1751. $match[2] = "0".$match[2];
  1752. }
  1753. if ( strlen($match[1]) == 1)
  1754. {
  1755. $match[1] = "0".$match[1];
  1756. }
  1757. return "{$match[3]}-{$match[1]}-{$match[2]}";
  1758. }
  1759. else
  1760. {
  1761. return "";
  1762. }
  1763. }
  1764. function clone_history(&$db, $from_id,$to_id, $to_type)
  1765. {
  1766. global $timedate;
  1767. $old_note_id=null;
  1768. $old_filename=null;
  1769. require_once('include/upload_file.php');
  1770. $tables = array('calls'=>'Call', 'meetings'=>'Meeting', 'notes'=>'Note', 'tasks'=>'Task');
  1771. $location=array('Email'=>"modules/Emails/Email.php",
  1772. 'Call'=>"modules/Calls/Call.php",
  1773. 'Meeting'=>"modules/Meetings/Meeting.php",
  1774. 'Note'=>"modules/Notes/Note.php",
  1775. 'Tasks'=>"modules/Tasks/Task.php",
  1776. );
  1777. foreach($tables as $table=>$bean_class)
  1778. {
  1779. if (!class_exists($bean_class))
  1780. {
  1781. require_once($location[$bean_class]);
  1782. }
  1783. $bProcessingNotes=false;
  1784. if ($table=='notes')
  1785. {
  1786. $bProcessingNotes=true;
  1787. }
  1788. $query = "SELECT id FROM $table WHERE parent_id='$from_id'";
  1789. $results = $db->query($query);
  1790. while($row = $db->fetchByAssoc($results))
  1791. {
  1792. //retrieve existing record.
  1793. $bean= new $bean_class();
  1794. $bean->retrieve($row['id']);
  1795. //process for new instance.
  1796. if ($bProcessingNotes)
  1797. {
  1798. $old_note_id=$row['id'];
  1799. $old_filename=$bean->filename;
  1800. }
  1801. $bean->id=null;
  1802. $bean->parent_id=$to_id;
  1803. $bean->parent_type=$to_type;
  1804. if ($to_type=='Contacts' and in_array('contact_id',$bean->column_fields))
  1805. {
  1806. $bean->contact_id=$to_id;
  1807. }
  1808. $bean->update_date_modified = false;
  1809. $bean->update_modified_by = false;
  1810. if(isset($bean->date_modified))
  1811. $bean->date_modified = $timedate->to_db($bean->date_modified);
  1812. if(isset($bean->date_entered))
  1813. $bean->date_entered = $timedate->to_db($bean->date_entered);
  1814. //save
  1815. $new_id=$bean->save();
  1816. //duplicate the file now. for notes.
  1817. if ($bProcessingNotes && !empty($old_filename))
  1818. {
  1819. UploadFile::duplicate_file($old_note_id,$new_id,$old_filename);
  1820. }
  1821. //reset the values needed for attachment duplication.
  1822. $old_note_id=null;
  1823. $old_filename=null;
  1824. }
  1825. }
  1826. }
  1827. function values_to_keys($array)
  1828. {
  1829. $new_array = array();
  1830. if(!is_array($array))
  1831. {
  1832. return $new_array;
  1833. }
  1834. foreach($array as $arr){
  1835. $new_array[$arr] = $arr;
  1836. }
  1837. return $new_array;
  1838. }
  1839. function clone_relationship(&$db, $tables = array(), $from_column, $from_id, $to_id)
  1840. {
  1841. foreach($tables as $table)
  1842. {
  1843. if ($table == 'emails_beans') {
  1844. $query = "SELECT * FROM $table WHERE $from_column='$from_id' and bean_module='Leads'";
  1845. } else {
  1846. $query = "SELECT * FROM $table WHERE $from_column='$from_id'";
  1847. }
  1848. $results = $db->query($query);
  1849. while($row = $db->fetchByAssoc($results))
  1850. {
  1851. $query = "INSERT INTO $table ";
  1852. $names = '';
  1853. $values = '';
  1854. $row[$from_column] = $to_id;
  1855. $row['id'] = create_guid();
  1856. if ($table=='emails_beans') {
  1857. $row['bean_module'] =='Contacts';
  1858. }
  1859. foreach($row as $name=>$value)
  1860. {
  1861. if(empty($names))
  1862. {
  1863. $names .= $name;
  1864. $values .= "'$value'";
  1865. } else
  1866. {
  1867. $names .= ', '. $name;
  1868. $values .= ", '$value'";
  1869. }
  1870. }
  1871. $query .= "($names) VALUES ($values)";
  1872. $db->query($query);
  1873. }
  1874. }
  1875. }
  1876. function get_unlinked_email_query($type, $bean) {
  1877. global $current_user;
  1878. $return_array['select']='SELECT emails.id ';
  1879. $return_array['from']='FROM emails ';
  1880. $return_array['where']="";
  1881. $return_array['join'] = " JOIN (select distinct email_id from emails_email_addr_rel eear
  1882. join email_addr_bean_rel eabr on eabr.bean_id ='$bean->id' and eabr.bean_module = '$bean->module_dir' and
  1883. eabr.email_address_id = eear.email_address_id and eabr.deleted=0
  1884. where eear.deleted=0 and eear.email_id not in
  1885. (select eb.email_id from emails_beans eb where eb.bean_module ='$bean->module_dir' and eb.bean_id = '$bean->id' and eb.deleted=0)
  1886. ) derivedemails on derivedemails.email_id = emails.id";
  1887. $return_array['join_tables'][0] = '';
  1888. if (isset($type) and isset($type['return_as_array']) and $type['return_as_array']==true) {
  1889. return $return_array;
  1890. }
  1891. return $return_array['select'] . $return_array['from'] . $return_array['where'];
  1892. } // fn
  1893. /**
  1894. * Check to see if the number is empty or non-zero
  1895. * @param $value
  1896. * @return boolean
  1897. **/
  1898. function number_empty($value)
  1899. {
  1900. return empty($value) && $value != '0';
  1901. }
  1902. function get_bean_select_array($add_blank=true, $bean_name, $display_columns, $where='', $order_by='', $blank_is_none=false)
  1903. {
  1904. global $beanFiles;
  1905. require_once($beanFiles[$bean_name]);
  1906. $focus = new $bean_name();
  1907. $user_array = array();
  1908. $user_array = get_register_value('select_array',$bean_name. $display_columns. $where . $order_by);
  1909. if(!$user_array)
  1910. {
  1911. $db = DBManagerFactory::getInstance();
  1912. $temp_result = Array();
  1913. $query = "SELECT id, {$display_columns} as display from {$focus->table_name} where ";
  1914. if ( $where != '')
  1915. {
  1916. $query .= $where." AND ";
  1917. }
  1918. $query .= " deleted=0";
  1919. if ( $order_by != '')
  1920. {
  1921. $query .= ' order by '.$order_by;
  1922. }
  1923. $GLOBALS['log']->debug("get_user_array query: $query");
  1924. $result = $db->query($query, true, "Error filling in user array: ");
  1925. if ($add_blank==true){
  1926. // Add in a blank row
  1927. if($blank_is_none == true) { // set 'blank row' to "--None--"
  1928. global $app_strings;
  1929. $temp_result[''] = $app_strings['LBL_NONE'];
  1930. } else {
  1931. $temp_result[''] = '';
  1932. }
  1933. }
  1934. // Get the id and the name.
  1935. while($row = $db->fetchByAssoc($result))
  1936. {
  1937. $temp_result[$row['id']] = $row['display'];
  1938. }
  1939. $user_array = $temp_result;
  1940. set_register_value('select_array',$bean_name. $display_columns. $where . $order_by,$temp_result);
  1941. }
  1942. return $user_array;
  1943. }
  1944. /**
  1945. *
  1946. *
  1947. * @param unknown_type $listArray
  1948. */
  1949. // function parse_list_modules
  1950. // searches a list for items in a user's allowed tabs and returns an array that removes unallowed tabs from list
  1951. function parse_list_modules(&$listArray)
  1952. {
  1953. global $modListHeader;
  1954. $returnArray = array();
  1955. foreach($listArray as $optionName => $optionVal)
  1956. {
  1957. if(array_key_exists($optionName, $modListHeader))
  1958. {
  1959. $returnArray[$optionName] = $optionVal;
  1960. }
  1961. // special case for products
  1962. if(array_key_exists('Products', $modListHeader))
  1963. {
  1964. $returnArray['ProductTemplates'] = $listArray['ProductTemplates'];
  1965. }
  1966. // special case for projects
  1967. if(array_key_exists('Project', $modListHeader))
  1968. {
  1969. $returnArray['ProjectTask'] = $listArray['ProjectTask'];
  1970. }
  1971. }
  1972. $acldenied = ACLController::disabledModuleList($listArray,false);
  1973. foreach($acldenied as $denied){
  1974. unset($returnArray[$denied]);
  1975. }
  1976. asort($returnArray);
  1977. return $returnArray;
  1978. }
  1979. function display_notice($msg = false){
  1980. global $error_notice;
  1981. //no error notice - lets just display the error to the user
  1982. if(!isset($error_notice)){
  1983. echo '<br>'.$msg . '<br>';
  1984. }else{
  1985. $error_notice .= $msg . '<br>';
  1986. }
  1987. }
  1988. /* checks if it is a number that atleast has the plus at the beggining
  1989. */
  1990. function skype_formatted($number){
  1991. //kbrill - BUG #15375
  1992. if($_REQUEST['action']=="Popup") {
  1993. return false;
  1994. } else {
  1995. return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 2) == '011';
  1996. }
  1997. // return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 2) == '011';
  1998. }
  1999. function format_skype($number) {
  2000. return preg_replace('/[^\+0-9]/','',$number);
  2001. }
  2002. function insert_charset_header() {
  2003. header('Content-Type: text/html; charset=UTF-8');
  2004. }
  2005. function getCurrentURL()
  2006. {
  2007. $href = "http:";
  2008. if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')
  2009. {
  2010. $href = 'https:';
  2011. }
  2012. $href.= "//".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
  2013. return $href;
  2014. }
  2015. function javascript_escape($str) {
  2016. $new_str = '';
  2017. for($i = 0; $i < strlen($str); $i++) {
  2018. if(ord(substr($str, $i, 1))==10){
  2019. $new_str .= '\n';
  2020. }elseif(ord(substr($str, $i, 1))==13){
  2021. $new_str .= '\r';
  2022. }
  2023. else {
  2024. $new_str .= $str{$i};
  2025. }
  2026. }
  2027. $new_str = str_replace("'", "\\'", $new_str);
  2028. return $new_str;
  2029. }
  2030. function js_escape($str, $keep=true){
  2031. $str = html_entity_decode(str_replace("\\", "", $str), ENT_QUOTES);
  2032. if($keep){
  2033. $str = javascript_escape($str);
  2034. }
  2035. else {
  2036. $str = str_replace("'", " ", $str);
  2037. $str = str_replace('"', " ", $str);
  2038. }
  2039. return $str;
  2040. //end function js_escape
  2041. }
  2042. function br2nl($str) {
  2043. $regex = "#<[^>]+br.+?>#";
  2044. preg_match_all($regex, $str, $matches);
  2045. foreach($matches[0] as $match) {
  2046. $str = str_replace($match, "<br>", $str);
  2047. }
  2048. $brs = array('<br>','<br/>', '<br />');
  2049. $str = str_replace("\r\n", "\n", $str); // make from windows-returns, *nix-returns
  2050. $str = str_replace("\n\r", "\n", $str); // make from windows-returns, *nix-returns
  2051. $str = str_replace("\r", "\n", $str); // make from windows-returns, *nix-returns
  2052. $str = str_replace($brs, "\n", $str); // to retrieve it
  2053. return $str;
  2054. }
  2055. /**
  2056. * Private helper function for displaying the contents of a given variable.
  2057. * This function is only intended to be used for SugarCRM internal development.
  2058. * The ppd stands for Pre Print Die.
  2059. */
  2060. function _ppd($mixed)
  2061. {
  2062. }
  2063. /**
  2064. * Private helper function for displaying the contents of a given variable in
  2065. * the Logger. This function is only intended to be used for SugarCRM internal
  2066. * development. The pp stands for Pre Print.
  2067. * @param $mixed var to print_r()
  2068. * @param $die boolean end script flow
  2069. * @param $displayStackTrace also show stack trace
  2070. */
  2071. function _ppl($mixed, $die=false, $displayStackTrace=false, $loglevel="fatal") {
  2072. }
  2073. /**
  2074. * private helper function to quickly show the major, direct, field attributes of a given bean.
  2075. * The ppf stands for Pre[formatted] Print Focus [object]
  2076. * @param object bean The focus bean
  2077. */
  2078. function _ppf($bean, $die=false) {
  2079. }
  2080. /**
  2081. * Private helper function for displaying the contents of a given variable.
  2082. * This function is only intended to be used for SugarCRM internal development.
  2083. * The pp stands for Pre Print.
  2084. */
  2085. function _pp($mixed)
  2086. {
  2087. }
  2088. /**
  2089. * Private helper function for displaying the contents of a given variable.
  2090. * This function is only intended to be used for SugarCRM internal development.
  2091. * The pp stands for Pre Print.
  2092. */
  2093. function _pstack_trace($mixed=NULL)
  2094. {
  2095. }
  2096. /**
  2097. * Private helper function for displaying the contents of a given variable.
  2098. * This function is only intended to be used for SugarCRM internal development.
  2099. * The pp stands for Pre Print Trace.
  2100. */
  2101. function _ppt($mixed, $textOnly=false)
  2102. {
  2103. }
  2104. /**
  2105. * Private helper function for displaying the contents of a given variable.
  2106. * This function is only intended to be used for SugarCRM internal development.
  2107. * The pp stands for Pre Print Trace Die.
  2108. */
  2109. function _pptd($mixed)
  2110. {
  2111. }
  2112. /**
  2113. * Private helper function for decoding javascript UTF8
  2114. * This function is only intended to be used for SugarCRM internal development.
  2115. */
  2116. function decodeJavascriptUTF8($str) {
  2117. }
  2118. /**
  2119. * Will check if a given PHP version string is supported (tested on this ver),
  2120. * unsupported (results unknown), or invalid (something will break on this
  2121. * ver). Do not pass in any pararameter to default to a check against the
  2122. * current environment's PHP version.
  2123. *
  2124. * @return 1 implies supported, 0 implies unsupported, -1 implies invalid
  2125. */
  2126. function check_php_version($sys_php_version = '') {
  2127. $sys_php_version = empty($sys_php_version) ? constant('PHP_VERSION') : $sys_php_version;
  2128. // versions below $min_considered_php_version considered invalid by default,
  2129. // versions equal to or above this ver will be considered depending
  2130. // on the rules that follow
  2131. $min_considered_php_version = '5.2.1';
  2132. // only the supported versions,
  2133. // should be mutually exclusive with $invalid_php_versions
  2134. $supported_php_versions = array (
  2135. '5.2.1', '5.2.2', '5.2.3', '5.2.4', '5.2.5', '5.2.6', '5.2.8',
  2136. );
  2137. //Find out what Database the system is using.
  2138. global $sugar_config;
  2139. $dbType = '';
  2140. if (isset($_REQUEST['setup_db_type'])) {
  2141. $dbType = $_REQUEST['setup_db_type'];
  2142. } else if (isset ($sugar_config['dbconfig']) && isset ($sugar_config['dbconfig']['db_type'])) {
  2143. $dbType = $sugar_config['dbconfig']['db_type'];
  2144. }
  2145. // invalid versions above the $min_considered_php_version,
  2146. // should be mutually exclusive with $supported_php_versions
  2147. // SugarCRM prohibits install on PHP 5.1.x on all platforms
  2148. $invalid_php_versions = array('5.2.7');
  2149. // default unsupported
  2150. $retval = 0;
  2151. // versions below $min_considered_php_version are invalid
  2152. if(1 == version_compare($sys_php_version, $min_considered_php_version, '<')) {
  2153. $retval = -1;
  2154. }
  2155. // supported version check overrides default unsupported
  2156. foreach($supported_php_versions as $ver) {
  2157. if(1 == version_compare($sys_php_version, $ver, 'eq') || strpos($sys_php_version,$ver) !== false) {
  2158. $retval = 1;
  2159. break;
  2160. }
  2161. }
  2162. // invalid version check overrides default unsupported
  2163. foreach($invalid_php_versions as $ver) {
  2164. if(1 == version_compare($sys_php_version, $ver, 'eq') && strpos($sys_php_version,$ver) !== false) {
  2165. $retval = -1;
  2166. break;
  2167. }
  2168. }
  2169. //allow a redhat distro to install, regardless of version. We are assuming the redhat naming convention is followed
  2170. //and the php version contains 'rh' characters
  2171. if(strpos($sys_php_version, 'rh') !== false) {
  2172. $retval = 1;
  2173. }
  2174. return $retval;
  2175. }
  2176. /**
  2177. * Will check if a given IIS version string is supported (tested on this ver),
  2178. * unsupported (results unknown), or invalid (something will break on this
  2179. * ver).
  2180. *
  2181. * @return 1 implies supported, 0 implies unsupported, -1 implies invalid
  2182. */
  2183. function check_iis_version($sys_iis_version = '') {
  2184. $server_software = $_SERVER["SERVER_SOFTWARE"];
  2185. $iis_version = '';
  2186. if(strpos($server_software,'Microsoft-IIS') !== false && preg_match_all("/^.*\/(\d+\.?\d*)$/", $server_software, $out))
  2187. $iis_version = $out[1][0];
  2188. $sys_iis_version = empty($sys_iis_version) ? $iis_version : $sys_iis_version;
  2189. // versions below $min_considered_iis_version considered invalid by default,
  2190. // versions equal to or above this ver will be considered depending
  2191. // on the rules that follow
  2192. $min_considered_iis_version = '6.0';
  2193. // only the supported versions,
  2194. // should be mutually exclusive with $invalid_iis_versions
  2195. $supported_iis_versions = array ('6.0', '7.0',);
  2196. $unsupported_iis_versions = array();
  2197. $invalid_iis_versions = array('5.0',);
  2198. // default unsupported
  2199. $retval = 0;
  2200. // versions below $min_considered_iis_version are invalid
  2201. if(1 == version_compare($sys_iis_version, $min_considered_iis_version, '<')) {
  2202. $retval = -1;
  2203. }
  2204. // supported version check overrides default unsupported
  2205. foreach($supported_iis_versions as $ver) {
  2206. if(1 == version_compare($sys_iis_version, $ver, 'eq') || strpos($sys_iis_version,$ver) !== false) {
  2207. $retval = 1;
  2208. break;
  2209. }
  2210. }
  2211. // unsupported version check overrides default unsupported
  2212. foreach($unsupported_iis_versions as $ver) {
  2213. if(1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version,$ver) !== false) {
  2214. $retval = 0;
  2215. break;
  2216. }
  2217. }
  2218. // invalid version check overrides default unsupported
  2219. foreach($invalid_iis_versions as $ver) {
  2220. if(1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version,$ver) !== false) {
  2221. $retval = -1;
  2222. break;
  2223. }
  2224. }
  2225. return $retval;
  2226. }
  2227. function pre_login_check(){
  2228. global $action, $login_error;
  2229. if(!empty($action)&& $action == 'Login'){
  2230. if(!empty($login_error)){
  2231. $login_error = htmlentities($login_error);
  2232. $login_error = str_replace(array("&lt;pre&gt;","&lt;/pre&gt;","\r\n", "\n"), "<br>", $login_error);
  2233. $_SESSION['login_error'] = $login_error;
  2234. echo '<script>
  2235. function set_focus() {}
  2236. if(document.getElementById("post_error")) {
  2237. document.getElementById("post_error").innerHTML="'. $login_error. '";
  2238. document.getElementById("cant_login").value=1;
  2239. document.getElementById("login_button").disabled = true;
  2240. document.getElementById("user_name").disabled = true;
  2241. //document.getElementById("user_password").disabled = true;
  2242. }
  2243. </script>';
  2244. }
  2245. }
  2246. }
  2247. function sugar_cleanup($exit = false) {
  2248. static $called = false;
  2249. if($called)return;
  2250. $called = true;
  2251. set_include_path(realpath(dirname(__FILE__) . '/..') . PATH_SEPARATOR . get_include_path());
  2252. chdir(realpath(dirname(__FILE__) . '/..'));
  2253. global $sugar_config;
  2254. LogicHook::initialize();
  2255. $GLOBALS['logic_hook']->call_custom_logic('', 'server_round_trip');
  2256. //added this check to avoid errors during install.
  2257. if (empty($sugar_config['dbconfig'])) {
  2258. if ($exit) exit; else return;
  2259. }
  2260. if (!class_exists('Tracker', true)) {
  2261. require_once 'modules/Trackers/Tracker.php';
  2262. }
  2263. Tracker::logPage();
  2264. // Now write the cached tracker_queries
  2265. if(!empty($GLOBALS['savePreferencesToDB']) && $GLOBALS['savePreferencesToDB']) {
  2266. if (!class_exists('UserPreference', true)) {
  2267. }
  2268. UserPreference::savePreferencesToDB();
  2269. }
  2270. pre_login_check();
  2271. if(class_exists('DBManagerFactory')) {
  2272. $db = DBManagerFactory::getInstance();
  2273. $db->disconnect();
  2274. if($exit) {
  2275. exit;
  2276. }
  2277. }
  2278. }
  2279. register_shutdown_function('sugar_cleanup');
  2280. /*
  2281. check_logic_hook - checks to see if your custom logic is in the logic file
  2282. if not, it will add it. If the file isn't built yet, it will create the file
  2283. */
  2284. function check_logic_hook_file($module_name, $event, $action_array){
  2285. require_once('include/utils/logic_utils.php');
  2286. $add_logic = false;
  2287. if(file_exists("custom/modules/$module_name/logic_hooks.php")){
  2288. $hook_array = get_hook_array($module_name);
  2289. if(check_existing_element($hook_array, $event, $action_array)==true){
  2290. //the hook at hand is present, so do nothing
  2291. } else {
  2292. $add_logic = true;
  2293. $logic_count = count($hook_array[$event]);
  2294. if($action_array[0]==""){
  2295. $action_array[0] = $logic_count + 1;
  2296. }
  2297. $hook_array[$event][] = $action_array;
  2298. }
  2299. //end if the file exists already
  2300. } else {
  2301. $add_logic = true;
  2302. if($action_array[0]==""){
  2303. $action_array[0] = 1;
  2304. }
  2305. $hook_array = array();
  2306. $hook_array[$event][] = $action_array;
  2307. //end if else file exists already
  2308. }
  2309. if($add_logic == true){
  2310. //reorder array by element[0]
  2311. //$hook_array = reorder_array($hook_array, $event);
  2312. //!!!Finish this above TODO
  2313. $new_contents = replace_or_add_logic_type($hook_array);
  2314. write_logic_file($module_name, $new_contents);
  2315. //end if add_element is true
  2316. }
  2317. //end function check_logic_hook_file
  2318. }
  2319. function remove_logic_hook($module_name, $event, $action_array) {
  2320. require_once('include/utils/logic_utils.php');
  2321. $add_logic = false;
  2322. if(file_exists("custom/modules/".$module_name."/logic_hooks.php")){
  2323. // The file exists, let's make sure the hook is there
  2324. $hook_array = get_hook_array($module_name);
  2325. if(check_existing_element($hook_array, $event, $action_array)==true){
  2326. // The hook is there, time to take it out.
  2327. foreach ( $hook_array[$event] as $i => $hook ) {
  2328. // We don't do a full comparison below just in case the filename changes
  2329. if ( $hook[0] == $action_array[0]
  2330. && $hook[1] == $action_array[1]
  2331. && $hook[3] == $action_array[3]
  2332. && $hook[4] == $action_array[4] ) {
  2333. unset($hook_array[$event][$i]);
  2334. }
  2335. }
  2336. $new_contents = replace_or_add_logic_type($hook_array);
  2337. write_logic_file($module_name, $new_contents);
  2338. }
  2339. }
  2340. }
  2341. function display_stack_trace($textOnly=false){
  2342. $stack = debug_backtrace();
  2343. echo "\n\n display_stack_trace caller, file: " . $stack[0]['file']. ' line#: ' .$stack[0]['line'];
  2344. if(!$textOnly)
  2345. echo '<br>';
  2346. $first = true;
  2347. $out = '';
  2348. foreach($stack as $item) {
  2349. $file = '';
  2350. $class = '';
  2351. $line = '';
  2352. $function = '';
  2353. if(isset($item['file']))
  2354. $file = $item['file'];
  2355. if(isset($item['class']))
  2356. $class = $item['class'];
  2357. if(isset($item['line']))
  2358. $line = $item['line'];
  2359. if(isset($item['function']))
  2360. $function = $item['function'];
  2361. if(!$first) {
  2362. if(!$textOnly) {
  2363. $out .= '<font color="black"><b>';
  2364. }
  2365. $out .= $file;
  2366. if(!$textOnly) {
  2367. $out .= '</b></font><font color="blue">';
  2368. }
  2369. $out .= "[L:{$line}]";
  2370. if(!$textOnly) {
  2371. $out .= '</font><font color="red">';
  2372. }
  2373. $out .= "({$class}:{$function})";
  2374. if(!$textOnly) {
  2375. $out .= '</font><br>';
  2376. } else {
  2377. $out .= "\n";
  2378. }
  2379. } else {
  2380. $first = false;
  2381. }
  2382. }
  2383. echo $out;
  2384. }
  2385. function StackTraceErrorHandler($errno, $errstr, $errfile,$errline, $errcontext) {
  2386. $error_msg = " $errstr occured in <b>$errfile</b> on line $errline [" . date("Y-m-d H:i:s") . ']';
  2387. $halt_script = true;
  2388. switch($errno){
  2389. case 2048: return; //depricated we have lots of these ignore them
  2390. case E_USER_NOTICE:
  2391. case E_NOTICE:
  2392. $halt_script = false;
  2393. $type = 'Notice';
  2394. break;
  2395. case E_USER_WARNING:
  2396. case E_COMPILE_WARNING:
  2397. case E_CORE_WARNING:
  2398. case E_WARNING:
  2399. $halt_script = false;
  2400. $type = "Warning";
  2401. break;
  2402. case E_USER_ERROR:
  2403. case E_COMPILE_ERROR:
  2404. case E_CORE_ERROR:
  2405. case E_ERROR:
  2406. $type = "Fatal Error";
  2407. break;
  2408. case E_PARSE:
  2409. $type = "Parse Error";
  2410. break;
  2411. default:
  2412. //don't know what it is might not be so bad
  2413. $halt_script = false;
  2414. $type = "Unknown Error ($errno)";
  2415. break;
  2416. }
  2417. $error_msg = '<b>'.$type.'</b>:' . $error_msg;
  2418. echo $error_msg;
  2419. display_stack_trace();
  2420. if($halt_script){
  2421. exit -1;
  2422. }
  2423. }
  2424. if(isset($sugar_config['stack_trace_errors']) && $sugar_config['stack_trace_errors']){
  2425. set_error_handler('StackTraceErrorHandler');
  2426. }
  2427. function get_sub_cookies($name){
  2428. $cookies = array();
  2429. if(isset($_COOKIE[$name])){
  2430. $subs = explode('#', $_COOKIE[$name]);
  2431. foreach($subs as $cookie){
  2432. if(!empty($cookie)){
  2433. $cookie = explode('=', $cookie);
  2434. $cookies[$cookie[0]] = $cookie[1];
  2435. }
  2436. }
  2437. }
  2438. return $cookies;
  2439. }
  2440. function mark_delete_components($sub_object_array, $run_second_level=false, $sub_sub_array=""){
  2441. if(!empty($sub_object_array)){
  2442. foreach($sub_object_array as $sub_object){
  2443. //run_second level is set to true if you need to remove sub-sub components
  2444. if($run_second_level==true){
  2445. mark_delete_components($sub_object->get_linked_beans($sub_sub_array['rel_field'],$sub_sub_array['rel_module']));
  2446. //end if run_second_level is true
  2447. }
  2448. $sub_object->mark_deleted($sub_object->id);
  2449. //end foreach sub component
  2450. }
  2451. //end if this is not empty
  2452. }
  2453. //end function mark_delete_components
  2454. }
  2455. /**
  2456. * For translating the php.ini memory values into bytes. e.g. input value of '8M' will return 8388608.
  2457. */
  2458. function return_bytes($val)
  2459. {
  2460. $val = trim($val);
  2461. $last = strtolower($val{strlen($val)-1});
  2462. switch($last)
  2463. {
  2464. // The 'G' modifier is available since PHP 5.1.0
  2465. case 'g':
  2466. $val *= 1024;
  2467. case 'm':
  2468. $val *= 1024;
  2469. case 'k':
  2470. $val *= 1024;
  2471. }
  2472. return $val;
  2473. }
  2474. /**
  2475. * Adds the href HTML tags around any URL in the $string
  2476. */
  2477. function url2html($string) {
  2478. //
  2479. $return_string = preg_replace('/(\w+:\/\/)(\S+)/', ' <a href="\\1\\2" target="_new" style="font-weight: normal;">\\1\\2</a>', $string);
  2480. return $return_string;
  2481. }
  2482. // End customization by Julian
  2483. /**
  2484. * tries to determine whether the Host machine is a Windows machine
  2485. */
  2486. function is_windows() {
  2487. static $is_windows = null;
  2488. if (!isset($is_windows)) {
  2489. $is_windows = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN';
  2490. }
  2491. return $is_windows;
  2492. }
  2493. /**
  2494. * equivalent for windows filesystem for PHP's is_writable()
  2495. * @param string file Full path to the file/dir
  2496. * @return bool true if writable
  2497. */
  2498. function is_writable_windows($file) {
  2499. if($file{strlen($file)-1}=='/') {
  2500. return is_writable_windows($file.uniqid(mt_rand()).'.tmp');
  2501. }
  2502. // the assumption here is that Windows has an inherited permissions scheme
  2503. // any file that is a descendant of an unwritable directory will inherit
  2504. // that property and will trigger a failure below.
  2505. if(is_dir($file)) {
  2506. return true;
  2507. }
  2508. $file = str_replace("/", '\\', $file);
  2509. if(file_exists($file)) {
  2510. if (!($f = @sugar_fopen($file, 'r+')))
  2511. return false;
  2512. fclose($f);
  2513. return true;
  2514. }
  2515. if(!($f = @sugar_fopen($file, 'w')))
  2516. return false;
  2517. fclose($f);
  2518. unlink($file);
  2519. return true;
  2520. }
  2521. /**
  2522. * best guesses Timezone based on webserver's TZ settings
  2523. */
  2524. function lookupTimezone($userOffset = 0){
  2525. require_once('include/timezone/timezones.php');
  2526. $defaultZones= array('America/New_York'=>1, 'America/Los_Angeles'=>1,'America/Chicago'=>1, 'America/Denver'=>1,'America/Anchorage'=>1, 'America/Phoenix'=>1, 'Europe/Amsterdam'=>1,'Europe/Athens'=>1,'Europe/London'=>1, 'Australia/Sydney'=>1, 'Australia/Perth'=>1);
  2527. global $timezones;
  2528. $serverOffset = date('Z');
  2529. if(date('I')) {
  2530. $serverOffset -= 3600;
  2531. }
  2532. if(!is_int($userOffset)) {
  2533. return '';
  2534. }
  2535. $gmtOffset = $serverOffset/60 + $userOffset * 60;
  2536. $selectedZone = ' ';
  2537. foreach($timezones as $zoneName=>$zone) {
  2538. if($zone['gmtOffset'] == $gmtOffset) {
  2539. $selectedZone = $zoneName;
  2540. }
  2541. if(!empty($defaultZones[$selectedZone]) ) {
  2542. return $selectedZone;
  2543. }
  2544. }
  2545. return $selectedZone;
  2546. }
  2547. function convert_module_to_singular($module_array){
  2548. global $beanList;
  2549. foreach($module_array as $key => $value){
  2550. if(!empty($beanList[$value])) $module_array[$key] = $beanList[$value];
  2551. if($value=="Cases") $module_array[$key] = "Case";
  2552. if($key=="projecttask"){
  2553. $module_array['ProjectTask'] = "Project Task";
  2554. unset($module_array[$key]);
  2555. }
  2556. }
  2557. return $module_array;
  2558. //end function convert_module_to_singular
  2559. }
  2560. /*
  2561. * Given the bean_name which may be plural or singular return the singular
  2562. * bean_name. This is important when you need to include files.
  2563. */
  2564. function get_singular_bean_name($bean_name){
  2565. global $beanFiles, $beanList;
  2566. if(array_key_exists($bean_name, $beanList)){
  2567. return $beanList[$bean_name];
  2568. }
  2569. else{
  2570. return $bean_name;
  2571. }
  2572. }
  2573. function get_label($label_tag, $temp_module_strings){
  2574. global $app_strings;
  2575. if(!empty($temp_module_strings[$label_tag])){
  2576. $label_name = $temp_module_strings[$label_tag];
  2577. } else {
  2578. if(!empty($app_strings[$label_tag])){
  2579. $label_name = $app_strings[$label_tag];
  2580. } else {
  2581. $label_name = $label_tag;
  2582. }
  2583. }
  2584. return $label_name;
  2585. //end function get_label
  2586. }
  2587. function search_filter_rel_info(& $focus, $tar_rel_module, $relationship_name){
  2588. $rel_list = array();
  2589. foreach($focus->relationship_fields as $rel_key => $rel_value){
  2590. if($rel_value == $relationship_name){
  2591. $temp_bean = get_module_info($tar_rel_module);
  2592. echo $focus->$rel_key;
  2593. $temp_bean->retrieve($focus->$rel_key);
  2594. if($temp_bean->id!=""){
  2595. $rel_list[] = $temp_bean;
  2596. return $rel_list;
  2597. }
  2598. }
  2599. }
  2600. return $rel_list;
  2601. //end function search_filter_rel_info
  2602. }
  2603. function get_module_info($module_name){
  2604. global $beanList;
  2605. global $dictionary;
  2606. //Get dictionary and focus data for module
  2607. $vardef_name = $beanList[$module_name];
  2608. if($vardef_name=="aCase"){
  2609. $class_name = "Case";
  2610. } else {
  2611. $class_name = $vardef_name;
  2612. }
  2613. if(!file_exists('modules/'. $module_name . '/'.$class_name.'.php')){
  2614. return;
  2615. }
  2616. include_once('modules/'. $module_name . '/'.$class_name.'.php');
  2617. $module_bean = new $vardef_name();
  2618. return $module_bean;
  2619. //end function get_module_table
  2620. }
  2621. /**
  2622. * In order to have one place to obtain the proper object name. aCase for example causes issues throughout the application.
  2623. *
  2624. * @param string $moduleName
  2625. */
  2626. function get_valid_bean_name($module_name){
  2627. global $beanList;
  2628. $vardef_name = $beanList[$module_name];
  2629. if($vardef_name=="aCase"){
  2630. $bean_name = "Case";
  2631. } else {
  2632. $bean_name = $vardef_name;
  2633. }
  2634. return $bean_name;
  2635. }
  2636. function checkAuthUserStatus(){
  2637. //authUserStatus();
  2638. }
  2639. /**
  2640. * This function returns an array of phpinfo() results that can be parsed and
  2641. * used to figure out what version we run, what modules are compiled in, etc.
  2642. * @param $level int info level constant (1,2,4,8...64);
  2643. * @return $returnInfo array array of info about the PHP environment
  2644. * @author original by "code at adspeed dot com" Fron php.net
  2645. * @author customized for Sugar by Chris N.
  2646. */
  2647. function getPhpInfo($level=-1) {
  2648. /** Name (constant) Value Description
  2649. INFO_GENERAL 1 The configuration line, php.ini location, build date, Web Server, System and more.
  2650. INFO_CREDITS 2 PHP Credits. See also phpcredits().
  2651. INFO_CONFIGURATION 4 Current Local and Master values for PHP directives. See also ini_get().
  2652. INFO_MODULES 8 Loaded modules and their respective settings. See also get_loaded_extensions().
  2653. INFO_ENVIRONMENT 16 Environment Variable information that's also available in $_ENV.
  2654. INFO_VARIABLES 32 Shows all predefined variables from EGPCS (Environment, GET, POST, Cookie, Server).
  2655. INFO_LICENSE 64 PHP License information. See also the license FAQ.
  2656. INFO_ALL -1 Shows all of the above. This is the default value.
  2657. */
  2658. ob_start();
  2659. phpinfo($level);
  2660. $phpinfo = ob_get_contents();
  2661. ob_end_clean();
  2662. $phpinfo = strip_tags($phpinfo,'<h1><h2><th><td>');
  2663. $phpinfo = preg_replace('/<th[^>]*>([^<]+)<\/th>/',"<info>\\1</info>",$phpinfo);
  2664. $phpinfo = preg_replace('/<td[^>]*>([^<]+)<\/td>/',"<info>\\1</info>",$phpinfo);
  2665. $parsedInfo = preg_split('/(<h.?>[^<]+<\/h.>)/', $phpinfo, -1, PREG_SPLIT_DELIM_CAPTURE);
  2666. $match = '';
  2667. $version = '';
  2668. $returnInfo = array();
  2669. if(preg_match('/<h1 class\=\"p\">PHP Version ([^<]+)<\/h1>/', $phpinfo, $version)) {
  2670. $returnInfo['PHP Version'] = $version[1];
  2671. }
  2672. for ($i=1; $i<count($parsedInfo); $i++) {
  2673. if (preg_match('/<h.>([^<]+)<\/h.>/', $parsedInfo[$i], $match)) {
  2674. $vName = trim($match[1]);
  2675. $parsedInfo2 = explode("\n",$parsedInfo[$i+1]);
  2676. foreach ($parsedInfo2 AS $vOne) {
  2677. $vPat = '<info>([^<]+)<\/info>';
  2678. $vPat3 = "/$vPat\s*$vPat\s*$vPat/";
  2679. $vPat2 = "/$vPat\s*$vPat/";
  2680. if (preg_match($vPat3,$vOne,$match)) { // 3cols
  2681. $returnInfo[$vName][trim($match[1])] = array(trim($match[2]),trim($match[3]));
  2682. } elseif (preg_match($vPat2,$vOne,$match)) { // 2cols
  2683. $returnInfo[$vName][trim($match[1])] = trim($match[2]);
  2684. }
  2685. }
  2686. } elseif(true) {
  2687. }
  2688. }
  2689. return $returnInfo;
  2690. }
  2691. /**
  2692. * This function will take a string that has tokens like {0}, {1} and will replace
  2693. * those tokens with the args provided
  2694. * @param $format string to format
  2695. * @param $args args to replace
  2696. * @return $result a formatted string
  2697. */
  2698. function string_format($format, $args){
  2699. $result = $format;
  2700. for($i = 0; $i < count($args); $i++){
  2701. $result = str_replace('{'.$i.'}', $args[$i], $result);
  2702. }
  2703. return $result;
  2704. }
  2705. /**
  2706. * Generate a string for displaying a unique identifier that is composed
  2707. * of a system_id and number. This is use to allow us to generate quote
  2708. * numbers using a DB auto-increment key from offline clients and still
  2709. * have the number be unique (since it is modified by the system_id.
  2710. *
  2711. * @param $num of bean
  2712. * @param $system_id from system
  2713. * @return $result a formatted string
  2714. */
  2715. function format_number_display($num, $system_id){
  2716. global $sugar_config;
  2717. if(isset($num) && !empty($num)){
  2718. $num=unformat_number($num);
  2719. if(isset($system_id) && $system_id == 1){
  2720. return sprintf("%d", $num);
  2721. }
  2722. else{
  2723. return sprintf("%d-%d", $num, $system_id);
  2724. }
  2725. }
  2726. }
  2727. function checkLoginUserStatus(){
  2728. }
  2729. /**
  2730. * This function will take a number and system_id and format
  2731. * @param $url URL containing host to append port
  2732. * @param $port the port number - if '' is passed, no change to url
  2733. * @return $resulturl the new URL with the port appended to the host
  2734. */
  2735. function appendPortToHost($url, $port)
  2736. {
  2737. $resulturl = $url;
  2738. // if no port, don't change the url
  2739. if($port != '')
  2740. {
  2741. $split = explode("/", $url);
  2742. //check if it starts with http, in case they didn't include that in url
  2743. if(str_begin($url, 'http'))
  2744. {
  2745. //third index ($split[2]) will be the host
  2746. $split[2] .= ":".$port;
  2747. }
  2748. else // otherwise assumed to start with host name
  2749. {
  2750. //first index ($split[0]) will be the host
  2751. $split[0] .= ":".$port;
  2752. }
  2753. $resulturl = implode("/", $split);
  2754. }
  2755. return $resulturl;
  2756. }
  2757. /**
  2758. * Singleton to return JSON object
  2759. * @return JSON object
  2760. */
  2761. function getJSONobj() {
  2762. static $json = null;
  2763. if(!isset($json)) {
  2764. require_once('include/JSON.php');
  2765. $json = new JSON(JSON_LOOSE_TYPE);
  2766. }
  2767. return $json;
  2768. }
  2769. require_once('include/utils/db_utils.php');
  2770. require_once('include/utils/user_utils.php');
  2771. //check to see if custom utils exists
  2772. if(file_exists('custom/include/custom_utils.php')){
  2773. include_once('custom/include/custom_utils.php');
  2774. }
  2775. /**
  2776. * Set default php.ini settings for entry points
  2777. */
  2778. function setPhpIniSettings() {
  2779. // zlib module
  2780. if(function_exists('gzclose') && headers_sent() == false) {
  2781. ini_set('zlib.output_compression', 1);
  2782. }
  2783. // mbstring module
  2784. //nsingh: breaks zip/unzip functionality. Commenting out 4/23/08
  2785. /*if(function_exists('mb_strlen')) {
  2786. ini_set('mbstring.func_overload', 7);
  2787. ini_set('mbstring.internal_encoding', 'UTF-8');
  2788. }*/
  2789. // http://us3.php.net/manual/en/ref.pcre.php#ini.pcre.backtrack-limit
  2790. // starting with 5.2.0, backtrack_limit breaks JSON decoding
  2791. $backtrack_limit = ini_get('pcre.backtrack_limit');
  2792. if(!empty($backtrack_limit)) {
  2793. ini_set('pcre.backtrack_limit', '-1');
  2794. }
  2795. // mssql only
  2796. if(ini_get("mssql.charset")) {
  2797. ini_set('mssql.charset', "UTF-8");
  2798. }
  2799. }
  2800. /**
  2801. * like array_merge() but will handle array elements that are themselves arrays;
  2802. * PHP's version just overwrites the element with the new one.
  2803. *
  2804. * @internal Note that this function deviates from the internal array_merge()
  2805. * functions in that it does does not treat numeric keys differently
  2806. * than string keys. Additionally, it deviates from
  2807. * array_merge_recursive() by not creating an array when like values
  2808. * found.
  2809. *
  2810. * @param array gimp the array whose values will be overloaded
  2811. * @param array dom the array whose values will pwn the gimp's
  2812. * @return array beaten gimp
  2813. */
  2814. function sugarArrayMerge($gimp, $dom) {
  2815. if(is_array($gimp) && is_array($dom)) {
  2816. foreach($dom as $domKey => $domVal) {
  2817. if(array_key_exists($domKey, $gimp)) {
  2818. if(is_array($domVal)) {
  2819. $tempArr = array();
  2820. foreach ( $domVal as $domArrKey => $domArrVal )
  2821. $tempArr[$domArrKey] = $domArrVal;
  2822. foreach ( $gimp[$domKey] as $gimpArrKey => $gimpArrVal )
  2823. if ( !array_key_exists($gimpArrKey, $tempArr) )
  2824. $tempArr[$gimpArrKey] = $gimpArrVal;
  2825. $gimp[$domKey] = $tempArr;
  2826. } else {
  2827. $gimp[$domKey] = $domVal;
  2828. }
  2829. } else {
  2830. $gimp[$domKey] = $domVal;
  2831. }
  2832. }
  2833. }
  2834. // if the passed value for gimp isn't an array, then return the $dom
  2835. elseif(is_array($dom))
  2836. return $dom;
  2837. return $gimp;
  2838. }
  2839. /**
  2840. * Similiar to sugarArrayMerge except arrays of N depth are merged.
  2841. *
  2842. * @param array gimp the array whose values will be overloaded
  2843. * @param array dom the array whose values will pwn the gimp's
  2844. * @return array beaten gimp
  2845. */
  2846. function sugarArrayMergeRecursive($gimp, $dom) {
  2847. if(is_array($gimp) && is_array($dom)) {
  2848. foreach($dom as $domKey => $domVal) {
  2849. if(array_key_exists($domKey, $gimp)) {
  2850. if(is_array($domVal) && is_array($gimp[$domKey])) {
  2851. $gimp[$domKey] = sugarArrayMergeRecursive($gimp[$domKey], $domVal);
  2852. } else {
  2853. $gimp[$domKey] = $domVal;
  2854. }
  2855. } else {
  2856. $gimp[$domKey] = $domVal;
  2857. }
  2858. }
  2859. }
  2860. // if the passed value for gimp isn't an array, then return the $dom
  2861. elseif(is_array($dom))
  2862. return $dom;
  2863. return $gimp;
  2864. }
  2865. /**
  2866. * finds the correctly working versions of PHP-JSON
  2867. * @return bool True if NOT found or WRONG version
  2868. */
  2869. function returnPhpJsonStatus() {
  2870. $goodVersions = array('1.1.1',);
  2871. if(function_exists('json_encode')) {
  2872. $phpInfo = getPhpInfo(8);
  2873. if(!in_array($phpInfo['json']['json version'], $goodVersions)) {
  2874. return true; // bad version found
  2875. } else {
  2876. return false; // all requirements met
  2877. }
  2878. }
  2879. return true; // not found
  2880. }
  2881. /**
  2882. * returns a 20-char or less string for the Tracker to display in the header
  2883. * @param string name field for a given Object
  2884. * @return string 20-char or less name
  2885. */
  2886. function getTrackerSubstring($name) {
  2887. $strlen = function_exists('mb_strlen') ? mb_strlen($name) : strlen($name);
  2888. if($strlen > 20) {
  2889. $chopped = function_exists('mb_substr') ? mb_substr($name, 0, 15) : substr($name, 0, 15);
  2890. } else {
  2891. $chopped = $name;
  2892. }
  2893. return $chopped;
  2894. }
  2895. function generate_search_where ($field_list=array(),$values=array(),&$bean,$add_custom_fields=false,$module='') {
  2896. $where_clauses= array();
  2897. $like_char='%';
  2898. $table_name=$bean->object_name;
  2899. foreach ($field_list[$module] as $field=>$parms) {
  2900. if(isset($values[$field]) && $values[$field] != "") {
  2901. $operator='like';
  2902. if (!empty($parms['operator'])) {
  2903. $operator=$parms['operator'];
  2904. }
  2905. if (is_array($values[$field])) {
  2906. $operator='in';
  2907. $field_value='';
  2908. foreach ($values[$field] as $key => $val) {
  2909. if ($val != ' ' and $val != '') {
  2910. if (!empty($field_value)) {
  2911. $field_value.=',';
  2912. }
  2913. $field_value .= "'".$GLOBALS['db']->quote($val)."'";
  2914. }
  2915. }
  2916. } else {
  2917. $field_value=$GLOBALS['db']->quote($values[$field]);
  2918. }
  2919. //set db_fields array.
  2920. if (!isset($parms['db_field']) ) {
  2921. $parms['db_field'] = array($field);
  2922. }
  2923. if (isset($parms['my_items']) and $parms['my_items'] == true) {
  2924. global $current_user;
  2925. $field_value = $GLOBALS['db']->quote($current_user->id);
  2926. $operator='=';
  2927. }
  2928. $where='';
  2929. $itr=0;
  2930. if ($field_value != '') {
  2931. foreach ($parms['db_field'] as $db_field) {
  2932. if (strstr($db_field,'.')===false) {
  2933. $db_field=$bean->table_name.".".$db_field;
  2934. }
  2935. if ($GLOBALS['db']->dbType=='oci8' && isset($parms['query_type']) && $parms['query_type']=='case_insensitive') {
  2936. $db_field='upper('.$db_field.")";
  2937. $field_value=strtoupper($field_value);
  2938. }
  2939. $itr++;
  2940. if (!empty($where)) {
  2941. $where .= " OR ";
  2942. }
  2943. switch (strtolower($operator)) {
  2944. case 'like' :
  2945. $where .= $db_field . " like '".$field_value.$like_char."'";
  2946. break;
  2947. case 'in':
  2948. $where .= $db_field . " in (".$field_value.')';
  2949. break;
  2950. case '=':
  2951. $where .= $db_field . " = '".$field_value ."'";
  2952. break;
  2953. }
  2954. }
  2955. }
  2956. if (!empty($where)) {
  2957. if ($itr>1) {
  2958. array_push($where_clauses, '( '.$where.' )');
  2959. } else {
  2960. array_push($where_clauses, $where);
  2961. }
  2962. }
  2963. }
  2964. }
  2965. if ($add_custom_fields) {
  2966. require_once('modules/DynamicFields/DynamicField.php');
  2967. $bean->setupCustomFields($module);
  2968. $bean->custom_fields->setWhereClauses($where_clauses);
  2969. }
  2970. return $where_clauses;
  2971. }
  2972. function add_quotes($str) {
  2973. return "'{$str}'";
  2974. }
  2975. /**
  2976. * This function will rebuild the config file
  2977. * @param $sugar_config
  2978. * @param $sugar_version
  2979. * @return bool true if successful
  2980. */
  2981. function rebuildConfigFile($sugar_config, $sugar_version) {
  2982. // add defaults to missing values of in-memory sugar_config
  2983. $sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config );
  2984. // need to override version with default no matter what
  2985. $sugar_config['sugar_version'] = $sugar_version;
  2986. ksort( $sugar_config );
  2987. if( write_array_to_file( "sugar_config", $sugar_config, "config.php" ) ){
  2988. return true;
  2989. }
  2990. else {
  2991. return false;
  2992. }
  2993. }
  2994. /**
  2995. * getJavascriptSiteURL
  2996. * This function returns a URL for the client javascript calls to access
  2997. * the site. It uses $_SERVER['HTTP_REFERER'] in the event that Proxy servers
  2998. * are used to access the site. Thus, the hostname in the URL returned may
  2999. * not always match that of $sugar_config['site_url']. Basically, the
  3000. * assumption is that however the user accessed the website is how they
  3001. * will continue to with subsequent javascript requests. If the variable
  3002. * $_SERVER['HTTP_REFERER'] is not found then we default to old algorithm.
  3003. * @return $site_url The url used to refer to the website
  3004. */
  3005. function getJavascriptSiteURL() {
  3006. global $sugar_config;
  3007. if(!empty($_SERVER['HTTP_REFERER'])) {
  3008. $url = parse_url($_SERVER['HTTP_REFERER']);
  3009. $replacement_url = $url['scheme']."://".$url['host'];
  3010. if(!empty($url['port']))
  3011. $replacement_url .= ':'.$url['port'];
  3012. $site_url = preg_replace('/^http[s]?\:\/\/[^\/]+/',$replacement_url,$sugar_config['site_url']);
  3013. } else {
  3014. $site_url = preg_replace('/^http(s)?\:\/\/[^\/]+/',"http$1://".$_SERVER['HTTP_HOST'],$sugar_config['site_url']);
  3015. if(!empty($_SERVER['SERVER_PORT']) &&$_SERVER['SERVER_PORT'] == '443') {
  3016. $site_url = preg_replace('/^http\:/','https:',$site_url);
  3017. }
  3018. }
  3019. $GLOBALS['log']->debug("getJavascriptSiteURL(), site_url=". $site_url);
  3020. return $site_url;
  3021. }
  3022. // works nicely with array_map() -- can be used to wrap single quotes around each element in an array
  3023. function add_squotes($str) {
  3024. return "'" . $str . "'";
  3025. }
  3026. // recursive function to count the number of levels within an array
  3027. function array_depth($array, $depth_count=-1, $depth_array=array()){
  3028. $depth_count++;
  3029. if (is_array($array)){
  3030. foreach ($array as $key => $value){
  3031. $depth_array[] = array_depth($value, $depth_count);
  3032. }
  3033. }
  3034. else{
  3035. return $depth_count;
  3036. }
  3037. foreach ($depth_array as $value){
  3038. $depth_count = $value > $depth_count ? $value : $depth_count;
  3039. }
  3040. return $depth_count;
  3041. }
  3042. /**
  3043. * Creates a new Group User
  3044. * @param string $name Name of Group User
  3045. * @return string GUID of new Group User
  3046. */
  3047. function createGroupUser($name) {
  3048. $group = new User();
  3049. $group->user_name = $name;
  3050. $group->last_name = $name;
  3051. $group->is_group = 1;
  3052. $group->deleted = 0;
  3053. $group->status = 'Active'; // cn: bug 6711
  3054. $timezone = lookupTimezone();
  3055. $group->setPreference('timezone', $timezone);
  3056. $group->save();
  3057. return $group->id;
  3058. }
  3059. /*
  3060. * Helper function to locate an icon file given only a name
  3061. * Searches through the various paths for the file
  3062. * @param string iconFileName The filename of the icon
  3063. * @return string Relative pathname of the located icon, or '' if not found
  3064. */
  3065. function _getIcon($iconFileName)
  3066. {
  3067. $iconPath = SugarThemeRegistry::current()->getImageURL("icon_{$iconFileName}.gif");
  3068. if ( empty($iconPath) )
  3069. $iconPath = SugarThemeRegistry::current()->getImageURL("{$iconFileName}.gif");
  3070. return $iconPath;
  3071. }
  3072. /**
  3073. * Function to grab the correct icon image for Studio
  3074. * @param string $iconFileName Name of the icon file
  3075. * @param string $altfilename Name of a fallback icon file (displayed if the imagefilename doesn't exist)
  3076. * @param string $width Width of image
  3077. * @param string $height Height of image
  3078. * @param string $align Alignment of image
  3079. * @return string $string <img> tag with corresponding image
  3080. */
  3081. function getStudioIcon($iconFileName='', $altFileName='', $width='48', $height='48', $align='baseline' )
  3082. {
  3083. global $app_strings, $theme;
  3084. $iconPath = _getIcon($iconFileName);
  3085. if(empty($iconPath)){
  3086. $iconPath = _getIcon($altFileName);
  3087. if (empty($iconPath))
  3088. {
  3089. return $app_strings['LBL_NO_IMAGE'];
  3090. }
  3091. }
  3092. return '<img border="0" src="'.$iconPath.'" width="'.$width.'" height="'.$height.'" align="'.$align.'">';
  3093. }
  3094. /**
  3095. * Function to grab the correct icon image for Dashlets Dialog
  3096. * @param string $filename Location of the icon file
  3097. * @param string $module Name of the module to fall back onto if file does not exist
  3098. * @param string $width Width of image
  3099. * @param string $height Height of image
  3100. * @param string $align Alignment of image
  3101. * @return string $string <img> tag with corresponding image
  3102. */
  3103. function get_dashlets_dialog_icon($module='', $width='32', $height='32', $align='absmiddle'){
  3104. global $app_strings, $theme;
  3105. $icon_path = _getIcon($module . "_32");
  3106. if (empty($icon_path))
  3107. {
  3108. $icon_path = _getIcon($module);
  3109. }
  3110. if(empty($icon_path)){
  3111. $icon = $app_strings['LBL_NO_IMAGE'];
  3112. }
  3113. else{
  3114. $icon = '<img border="0" src="'.$icon_path.'" width="'.$width.'" height="'.$height.'" align="'.$align.'">';
  3115. }
  3116. return $icon;
  3117. }
  3118. // works nicely to change UTF8 strings that are html entities - good for PDF conversions
  3119. function html_entity_decode_utf8($string)
  3120. {
  3121. static $trans_tbl;
  3122. // replace numeric entities
  3123. $string = preg_replace('~&#x([0-9a-f]+);~ei', 'code2utf(hexdec("\\1"))', $string);
  3124. $string = preg_replace('~&#([0-9]+);~e', 'code2utf(\\1)', $string);
  3125. // replace literal entities
  3126. if (!isset($trans_tbl))
  3127. {
  3128. $trans_tbl = array();
  3129. foreach (get_html_translation_table(HTML_ENTITIES) as $val=>$key)
  3130. $trans_tbl[$key] = utf8_encode($val);
  3131. }
  3132. return strtr($string, $trans_tbl);
  3133. }
  3134. // Returns the utf string corresponding to the unicode value
  3135. function code2utf($num)
  3136. {
  3137. if ($num < 128) return chr($num);
  3138. if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
  3139. if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
  3140. if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
  3141. return '';
  3142. }
  3143. function str_split_php4($string, $length = 1) {
  3144. $string_length = strlen($string);
  3145. $return = array();
  3146. $cursor = 0;
  3147. if ($length > $string_length) {
  3148. // use the string_length as the string is shorter than the length
  3149. $length = $string_length;
  3150. }
  3151. for ($cursor = 0; $cursor < $string_length; $cursor = $cursor + $length) {
  3152. $return[] = substr($string, $cursor, $length);
  3153. }
  3154. return $return;
  3155. }
  3156. if (version_compare(phpversion(), '5.0.0', '<')) {
  3157. function str_split($string, $length = 1) {
  3158. return str_split_php4($string, $length);
  3159. }
  3160. }
  3161. /*
  3162. * Invoked when connected to mssql. checks if we have freetds version of mssql library.
  3163. * the response is put into a global variable.
  3164. */
  3165. function is_freetds() {
  3166. $ret=false;
  3167. if (isset($GLOBALS['mssql_library_version'])) {
  3168. if ($GLOBALS['mssql_library_version']=='freetds') {
  3169. $ret=true;
  3170. } else {
  3171. $ret=false;
  3172. }
  3173. } else {
  3174. ob_start();
  3175. phpinfo();
  3176. $info=ob_get_contents();
  3177. ob_end_clean();
  3178. if (strpos($info,'FreeTDS') !== false) {
  3179. $GLOBALS['mssql_library_version']='freetds';
  3180. $ret=true;
  3181. } else {
  3182. $GLOBALS['mssql_library_version']='regular';
  3183. $ret=false;
  3184. }
  3185. }
  3186. return $ret;
  3187. }
  3188. /*
  3189. * stripos - Find position of first occurrence of a case-insensitive string
  3190. *
  3191. * The function is being defined for systems with PHP version < 5.
  3192. *
  3193. */
  3194. if (!function_exists("stripos")){
  3195. function stripos($haystack,$needle,$offset=0){
  3196. return strpos(strtolower($haystack),strtolower($needle),$offset);
  3197. }
  3198. }
  3199. /**
  3200. * Chart dashlet helper function that returns the correct CSS file, dependent on the current theme.
  3201. *
  3202. * @todo this won't work completely right until we impliment css compression and combination
  3203. * for now, we'll just include the last css file found.
  3204. *
  3205. * @return chart.css file to use
  3206. */
  3207. function chartStyle()
  3208. {
  3209. return SugarThemeRegistry::current()->getCSSURL('chart.css');
  3210. }
  3211. /**
  3212. * Chart dashlet helper functions that returns the correct XML color file for charts,
  3213. * dependent on the current theme.
  3214. *
  3215. * @return sugarColors.xml to use
  3216. */
  3217. function chartColors()
  3218. {
  3219. return SugarThemeRegistry::current()->getImageURL('sugarColors.xml');
  3220. }
  3221. /* End Chart Dashlet helper functions */
  3222. /**
  3223. * This function is designed to set up the php enviroment
  3224. * for AJAX requests.
  3225. */
  3226. function ajaxInit() {
  3227. ini_set('display_errors', 'false');
  3228. }
  3229. /**
  3230. * Returns an absolute path from the given path, determining if it is relative or absolute
  3231. *
  3232. * @param string $path
  3233. * @return string
  3234. */
  3235. function getAbsolutePath(
  3236. $path,
  3237. $currentServer = false
  3238. )
  3239. {
  3240. $path = trim($path);
  3241. // try to match absolute paths like \\server\share, /directory or c:\
  3242. if ( ( substr($path,0,2) == '\\\\' )
  3243. || ( $path[0] == '/' )
  3244. || preg_match('/^[A-z]:/i',$path)
  3245. || $currentServer )
  3246. return $path;
  3247. return getcwd().'/'.$path;
  3248. }
  3249. /**
  3250. * Returns the bean object of the given module
  3251. *
  3252. * @param string $module
  3253. * @return object
  3254. */
  3255. function loadBean(
  3256. $module
  3257. )
  3258. {
  3259. global $beanList, $beanFiles;
  3260. if ( !isset($beanList) || !isset($beanFiles) )
  3261. require('include/modules.php');
  3262. if ( isset($beanList[$module]) ) {
  3263. $bean = $beanList[$module];
  3264. if(isset($beanFiles[$bean])){
  3265. require_once($beanFiles[$bean]);
  3266. $focus = new $bean();
  3267. }else {
  3268. return false;
  3269. }
  3270. }
  3271. else {
  3272. return false;
  3273. }
  3274. return $focus;
  3275. }
  3276. /**
  3277. * Returns the shortcut keys to access the shortcut links. Shortcut
  3278. * keys vary depending on browser versions and operating systems.
  3279. * @return String value of the shortcut keys
  3280. */
  3281. function get_alt_hot_key() {
  3282. $ua = '';
  3283. if ( isset($_SERVER['HTTP_USER_AGENT']) )
  3284. $ua = strtolower($_SERVER['HTTP_USER_AGENT']);
  3285. $isMac = strpos($ua, 'mac') !== false;
  3286. $isLinux = strpos($ua, 'linux') !== false;
  3287. if(!$isMac && !$isLinux && strpos($ua, 'mozilla') !== false) {
  3288. if(preg_match('/firefox\/(\d)?\./', $ua, $matches)) {
  3289. return $matches[1] < 2 ? 'Alt+' : 'Alt+Shift+';
  3290. }
  3291. }
  3292. return $isMac ? 'Ctrl+' : 'Alt+';
  3293. }
  3294. function can_start_session(){
  3295. if(!empty($_GET['PHPSESSID'])) {
  3296. return true;
  3297. }
  3298. $session_id = session_id();
  3299. return empty($session_id) ? true : false;
  3300. }
  3301. function load_link_class($properties){
  3302. $class = 'Link';
  3303. if(!empty($properties['link_class']) && !empty($properties['link_file'])){
  3304. require_once($properties['link_file']);
  3305. $class = $properties['link_class'];
  3306. }
  3307. return $class;
  3308. }
  3309. function inDeveloperMode()
  3310. {
  3311. return isset($GLOBALS['sugar_config']['developerMode']) && $GLOBALS['sugar_config']['developerMode'];
  3312. }
  3313. /**
  3314. * The function is used because currently we are not supporting mbstring.func_overload
  3315. * 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.
  3316. * 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.
  3317. * @returns the substred strings.
  3318. */
  3319. function sugar_substr($string, $length, $charset='UTF-8') {
  3320. if($GLOBALS['db']->dbType == 'mssql' && empty($GLOBALS['db']->isFreeTDS)) {
  3321. if(strlen($string) > $length) {
  3322. $string = trim(substr(trim($string),0,$length));
  3323. }
  3324. }
  3325. else {
  3326. if(mb_strlen($string,$charset) > $length) {
  3327. $string = trim(mb_substr(trim($string),0,$length,$charset));
  3328. }
  3329. }
  3330. return $string;
  3331. }
  3332. /**
  3333. * create_export_query is used for export and massupdate
  3334. * We haven't handle the these fields: $field['type'] == 'relate' && isset($field['link']
  3335. * This function will correct the where clause and output necessary join condition for them
  3336. * @param $module: the module name
  3337. * @param $searchFields: searchFields which is got after $searchForm->populateFromArray()
  3338. * @param $where: where clauses
  3339. * @return $ret_array['where']: corrected where clause
  3340. * @return $ret_array['join']: extra join condition
  3341. */
  3342. function create_export_query_relate_link_patch($module, $searchFields, $where){
  3343. if(file_exists('modules/'.$module.'/SearchForm.html')){
  3344. $ret_array['where'] = $where;
  3345. return $ret_array;
  3346. }
  3347. $seed = loadBean($module);
  3348. foreach($seed->field_defs as $name=>$field)
  3349. {
  3350. if( $field['type'] == 'relate' && isset($field['link']) && !empty($searchFields[$name]['value']) ){
  3351. $seed->load_relationship($field['link']);
  3352. $params = array();
  3353. if(empty($join_type))
  3354. {
  3355. $params['join_type'] = ' LEFT JOIN ';
  3356. }
  3357. else
  3358. {
  3359. $params['join_type'] = $join_type;
  3360. }
  3361. if(isset($data['join_name']))
  3362. {
  3363. $params['join_table_alias'] = $field['join_name'];
  3364. }
  3365. else
  3366. {
  3367. $params['join_table_alias'] = 'join_'.$field['name'];
  3368. }
  3369. if(isset($data['join_link_name']))
  3370. {
  3371. $params['join_table_link_alias'] = $field['join_link_name'];
  3372. }
  3373. else
  3374. {
  3375. $params['join_table_link_alias'] = 'join_link_'.$field['name'];
  3376. }
  3377. $join = $seed->$field['link']->getJoin($params, true);
  3378. $join_table_alias = 'join_'.$field['name'];
  3379. if(isset($field['db_concat_fields'])){
  3380. $db_field = db_concat($join_table_alias, $field['db_concat_fields']);
  3381. $where = preg_replace('/'.$field['name'].'/', $db_field, $where);
  3382. }else{
  3383. $where = preg_replace('/(^|[\s(])' . $field['name'] . '/', '${1}' . $join_table_alias . '.'.$field['rname'], $where);
  3384. }
  3385. }
  3386. }
  3387. $ret_array = array('where'=>$where, 'join'=>$join['join']);
  3388. return $ret_array;
  3389. }