1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* |
4
|
|
|
* SugarCRM Community Edition is a customer relationship management program developed by |
5
|
|
|
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
6
|
|
|
* |
7
|
|
|
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd. |
8
|
|
|
* Copyright (C) 2011 - 2016 SalesAgility Ltd. |
9
|
|
|
* |
10
|
|
|
* This program is free software; you can redistribute it and/or modify it under |
11
|
|
|
* the terms of the GNU Affero General Public License version 3 as published by the |
12
|
|
|
* Free Software Foundation with the addition of the following permission added |
13
|
|
|
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
14
|
|
|
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
15
|
|
|
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
16
|
|
|
* |
17
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT |
18
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
19
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
20
|
|
|
* details. |
21
|
|
|
* |
22
|
|
|
* You should have received a copy of the GNU Affero General Public License along with |
23
|
|
|
* this program; if not, see http://www.gnu.org/licenses or write to the Free |
24
|
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
25
|
|
|
* 02110-1301 USA. |
26
|
|
|
* |
27
|
|
|
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
28
|
|
|
* SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
29
|
|
|
* |
30
|
|
|
* The interactive user interfaces in modified source and object code versions |
31
|
|
|
* of this program must display Appropriate Legal Notices, as required under |
32
|
|
|
* Section 5 of the GNU Affero General Public License version 3. |
33
|
|
|
* |
34
|
|
|
* In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
35
|
|
|
* these Appropriate Legal Notices must retain the display of the "Powered by |
36
|
|
|
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
37
|
|
|
* reasonably feasible for technical reasons, the Appropriate Legal Notices must |
38
|
|
|
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
39
|
|
|
*/ |
40
|
|
|
|
41
|
|
|
/********************************************************************************* |
42
|
|
|
* Description: Includes generic helper functions used throughout the application. |
43
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
44
|
|
|
* All Rights Reserved. |
45
|
|
|
* Contributor(s): ______________________________________.. |
46
|
|
|
********************************************************************************/ |
47
|
|
|
require_once 'include/SugarObjects/SugarConfig.php'; |
48
|
|
|
require_once 'include/utils/security_utils.php'; |
49
|
|
|
|
50
|
|
|
function make_sugar_config(&$sugar_config) |
51
|
|
|
{ |
52
|
|
|
/* used to convert non-array config.php file to array format */ |
53
|
|
|
global $admin_export_only; |
54
|
|
|
global $cache_dir; |
55
|
|
|
global $calculate_response_time; |
56
|
|
|
global $create_default_user; |
57
|
|
|
global $dateFormats; |
58
|
|
|
global $dbconfig; |
59
|
|
|
global $dbconfigoption; |
60
|
|
|
global $default_action; |
61
|
|
|
global $default_charset; |
62
|
|
|
global $default_currency_name; |
63
|
|
|
global $default_currency_symbol; |
64
|
|
|
global $default_currency_iso4217; |
65
|
|
|
global $defaultDateFormat; |
66
|
|
|
global $default_language; |
67
|
|
|
global $default_module; |
68
|
|
|
global $default_password; |
69
|
|
|
global $default_theme; |
70
|
|
|
global $defaultTimeFormat; |
71
|
|
|
global $default_user_is_admin; |
72
|
|
|
global $default_user_name; |
73
|
|
|
global $disable_export; |
74
|
|
|
global $disable_persistent_connections; |
75
|
|
|
global $display_email_template_variable_chooser; |
76
|
|
|
global $display_inbound_email_buttons; |
77
|
|
|
global $history_max_viewed; |
78
|
|
|
global $host_name; |
79
|
|
|
global $import_dir; |
80
|
|
|
global $languages; |
81
|
|
|
global $list_max_entries_per_page; |
82
|
|
|
global $lock_default_user_name; |
83
|
|
|
global $log_memory_usage; |
84
|
|
|
global $nameFormats; |
85
|
|
|
global $requireAccounts; |
86
|
|
|
global $RSS_CACHE_TIME; |
87
|
|
|
global $session_dir; |
88
|
|
|
global $site_URL; |
89
|
|
|
global $site_url; |
90
|
|
|
global $sugar_version; |
91
|
|
|
global $timeFormats; |
92
|
|
|
global $tmp_dir; |
93
|
|
|
global $translation_string_prefix; |
94
|
|
|
global $unique_key; |
95
|
|
|
global $upload_badext; |
96
|
|
|
global $upload_dir; |
97
|
|
|
global $upload_maxsize; |
98
|
|
|
global $import_max_execution_time; |
99
|
|
|
global $list_max_entries_per_subpanel; |
100
|
|
|
global $passwordsetting; |
101
|
|
|
|
102
|
|
|
// assumes the following variables must be set: |
103
|
|
|
// $dbconfig, $dbconfigoption, $cache_dir, $session_dir, $site_URL, $upload_dir |
104
|
|
|
|
105
|
|
|
$sugar_config = array( |
106
|
|
|
'admin_export_only' => empty($admin_export_only) ? false : $admin_export_only, |
107
|
|
|
'export_delimiter' => empty($export_delimiter) ? ',' : $export_delimiter, |
108
|
|
|
'cache_dir' => empty($cache_dir) ? 'cache/' : $cache_dir, |
109
|
|
|
'calculate_response_time' => empty($calculate_response_time) ? true : $calculate_response_time, |
110
|
|
|
'create_default_user' => empty($create_default_user) ? false : $create_default_user, |
111
|
|
|
'chartEngine' => 'Jit', |
112
|
|
|
'date_formats' => empty($dateFormats) ? array( |
113
|
|
|
'Y-m-d' => '2010-12-23', |
114
|
|
|
'd-m-Y' => '23-12-2010', |
115
|
|
|
'm-d-Y' => '12-23-2010', |
116
|
|
|
'Y/m/d' => '2010/12/23', |
117
|
|
|
'd/m/Y' => '23/12/2010', |
118
|
|
|
'm/d/Y' => '12/23/2010', |
119
|
|
|
'Y.m.d' => '2010.12.23', |
120
|
|
|
'd.m.Y' => '23.12.2010', |
121
|
|
|
'm.d.Y' => '12.23.2010', |
122
|
|
|
) : $dateFormats, |
123
|
|
|
'dbconfig' => $dbconfig, // this must be set!! |
124
|
|
|
'dbconfigoption' => $dbconfigoption, // this must be set!! |
125
|
|
|
'default_action' => empty($default_action) ? 'index' : $default_action, |
126
|
|
|
'default_charset' => empty($default_charset) ? 'UTF-8' : $default_charset, |
127
|
|
|
'default_currency_name' => empty($default_currency_name) ? 'US Dollar' : $default_currency_name, |
128
|
|
|
'default_currency_symbol' => empty($default_currency_symbol) ? '$' : $default_currency_symbol, |
129
|
|
|
'default_currency_iso4217' => empty($default_currency_iso4217) ? '$' : $default_currency_iso4217, |
130
|
|
|
'default_date_format' => empty($defaultDateFormat) ? 'm/d/Y' : $defaultDateFormat, |
131
|
|
|
'default_locale_name_format' => empty($defaultNameFormat) ? 's f l' : $defaultNameFormat, |
132
|
|
|
'default_export_charset' => 'UTF-8', |
133
|
|
|
'default_language' => empty($default_language) ? 'en_us' : $default_language, |
134
|
|
|
'default_module' => empty($default_module) ? 'Home' : $default_module, |
135
|
|
|
'default_password' => empty($default_password) ? '' : $default_password, |
136
|
|
|
'default_permissions' => array( |
137
|
|
|
'dir_mode' => 02770, |
138
|
|
|
'file_mode' => 0755, |
139
|
|
|
'chown' => '', |
140
|
|
|
'chgrp' => '', |
141
|
|
|
), |
142
|
|
|
'default_theme' => empty($default_theme) ? 'Sugar5' : $default_theme, |
143
|
|
|
'default_time_format' => empty($defaultTimeFormat) ? 'h:ia' : $defaultTimeFormat, |
144
|
|
|
'default_user_is_admin' => empty($default_user_is_admin) ? false : $default_user_is_admin, |
145
|
|
|
'default_user_name' => empty($default_user_name) ? '' : $default_user_name, |
146
|
|
|
'disable_export' => empty($disable_export) ? false : $disable_export, |
147
|
|
|
'disable_persistent_connections' => empty($disable_persistent_connections) ? false : $disable_persistent_connections, |
148
|
|
|
'display_email_template_variable_chooser' => empty($display_email_template_variable_chooser) ? false : $display_email_template_variable_chooser, |
149
|
|
|
'display_inbound_email_buttons' => empty($display_inbound_email_buttons) ? false : $display_inbound_email_buttons, |
150
|
|
|
'history_max_viewed' => empty($history_max_viewed) ? 50 : $history_max_viewed, |
151
|
|
|
'host_name' => empty($host_name) ? 'localhost' : $host_name, |
152
|
|
|
'import_dir' => $import_dir, // this must be set!! |
153
|
|
|
'import_max_records_per_file' => 100, |
154
|
|
|
'import_max_records_total_limit' => '', |
155
|
|
|
'languages' => empty($languages) ? array('en_us' => 'English (US)') : $languages, |
156
|
|
|
'list_max_entries_per_page' => empty($list_max_entries_per_page) ? 20 : $list_max_entries_per_page, |
157
|
|
|
'list_max_entries_per_subpanel' => empty($list_max_entries_per_subpanel) ? 10 : $list_max_entries_per_subpanel, |
158
|
|
|
'lock_default_user_name' => empty($lock_default_user_name) ? false : $lock_default_user_name, |
159
|
|
|
'log_memory_usage' => empty($log_memory_usage) ? false : $log_memory_usage, |
160
|
|
|
'name_formats' => empty($nameFormats) ? array( |
161
|
|
|
's f l' => 's f l', 'f l' => 'f l', 's l' => 's l', 'l, s f' => 'l, s f', |
162
|
|
|
'l, f' => 'l, f', 's l, f' => 's l, f', 'l s f' => 'l s f', 'l f s' => 'l f s', |
163
|
|
|
) : $nameFormats, |
164
|
|
|
'portal_view' => 'single_user', |
165
|
|
|
'resource_management' => array( |
166
|
|
|
'special_query_limit' => 50000, |
167
|
|
|
'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'), |
168
|
|
|
'default_limit' => 1000, |
169
|
|
|
), |
170
|
|
|
'require_accounts' => empty($requireAccounts) ? true : $requireAccounts, |
171
|
|
|
'rss_cache_time' => empty($RSS_CACHE_TIME) ? '10800' : $RSS_CACHE_TIME, |
172
|
|
|
'session_dir' => $session_dir, // this must be set!! |
173
|
|
|
'site_url' => empty($site_URL) ? $site_url : $site_URL, // this must be set!! |
174
|
|
|
'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable |
175
|
|
|
'showThemePicker' => true, |
176
|
|
|
'sugar_version' => empty($sugar_version) ? 'unknown' : $sugar_version, |
177
|
|
|
'time_formats' => empty($timeFormats) ? array( |
178
|
|
|
'H:i' => '23:00', 'h:ia' => '11:00 pm', 'h:iA' => '11:00PM', |
179
|
|
|
'H.i' => '23.00', 'h.ia' => '11.00 pm', 'h.iA' => '11.00PM', ) : $timeFormats, |
180
|
|
|
'tmp_dir' => $tmp_dir, // this must be set!! |
181
|
|
|
'translation_string_prefix' => empty($translation_string_prefix) ? false : $translation_string_prefix, |
182
|
|
|
'unique_key' => empty($unique_key) ? md5(create_guid()) : $unique_key, |
183
|
|
|
'upload_badext' => empty($upload_badext) ? array( |
184
|
|
|
'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py', |
185
|
|
|
'asp', 'cfm', 'js', 'vbs', 'html', 'htm', ) : $upload_badext, |
186
|
|
|
'upload_dir' => $upload_dir, // this must be set!! |
187
|
|
|
'upload_maxsize' => empty($upload_maxsize) ? 30000000 : $upload_maxsize, |
188
|
|
|
'import_max_execution_time' => empty($import_max_execution_time) ? 3600 : $import_max_execution_time, |
189
|
|
|
'lock_homepage' => false, |
190
|
|
|
'lock_subpanels' => false, |
191
|
|
|
'max_dashlets_homepage' => 15, |
192
|
|
|
'dashlet_display_row_options' => array('1', '3', '5', '10'), |
193
|
|
|
'default_max_tabs' => empty($max_tabs) ? '7' : $max_tabs, |
194
|
|
|
'default_subpanel_tabs' => empty($subpanel_tabs) ? true : $subpanel_tabs, |
195
|
|
|
'default_subpanel_links' => empty($subpanel_links) ? false : $subpanel_links, |
196
|
|
|
'default_swap_last_viewed' => empty($swap_last_viewed) ? false : $swap_last_viewed, |
197
|
|
|
'default_swap_shortcuts' => empty($swap_shortcuts) ? false : $swap_shortcuts, |
198
|
|
|
'default_navigation_paradigm' => empty($navigation_paradigm) ? 'gm' : $navigation_paradigm, |
199
|
|
|
'default_call_status' => 'Planned', |
200
|
|
|
'js_lang_version' => 1, |
201
|
|
|
'passwordsetting' => empty($passwordsetting) ? array( |
202
|
|
|
'SystemGeneratedPasswordON' => '', |
203
|
|
|
'generatepasswordtmpl' => '', |
204
|
|
|
'lostpasswordtmpl' => '', |
205
|
|
|
'forgotpasswordON' => true, |
206
|
|
|
'linkexpiration' => '1', |
207
|
|
|
'linkexpirationtime' => '30', |
208
|
|
|
'linkexpirationtype' => '1', |
209
|
|
|
'systexpiration' => '0', |
210
|
|
|
'systexpirationtime' => '', |
211
|
|
|
'systexpirationtype' => '0', |
212
|
|
|
'systexpirationlogin' => '', |
213
|
|
|
) : $passwordsetting, |
214
|
|
|
'use_sprites' => function_exists('imagecreatetruecolor'), |
215
|
|
|
'search_wildcard_infront' => false, |
216
|
|
|
'search_wildcard_char' => '%', |
217
|
|
|
'jobs' => array( |
218
|
|
|
'min_retry_interval' => 60, // minimal job retry delay |
219
|
|
|
'max_retries' => 5, // how many times to retry the job |
220
|
|
|
'timeout' => 86400, // how long a job may spend as running before being force-failed |
221
|
|
|
'soft_lifetime' => 7, // how many days until job record will be soft deleted after completion |
222
|
|
|
'hard_lifetime' => 21, // how many days until job record will be purged from DB |
223
|
|
|
), |
224
|
|
|
'cron' => array( |
225
|
|
|
'max_cron_jobs' => 10, // max jobs per cron schedule run |
226
|
|
|
'max_cron_runtime' => 60, // max runtime for cron jobs |
227
|
|
|
'min_cron_interval' => 30, // minimal interval between cron jobs |
228
|
|
|
), |
229
|
|
|
); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
function get_sugar_config_defaults() |
233
|
|
|
{ |
234
|
|
|
global $locale; |
235
|
|
|
/* |
236
|
|
|
* used for getting base values for array style config.php. used by the |
237
|
|
|
* installer and to fill in new entries on upgrades. see also: |
238
|
|
|
* sugar_config_union |
239
|
|
|
*/ |
240
|
|
|
|
241
|
|
|
$sugar_config_defaults = array( |
242
|
|
|
'admin_export_only' => false, |
243
|
|
|
'export_delimiter' => ',', |
244
|
|
|
'export_excel_compatible' => false, |
245
|
|
|
'cache_dir' => 'cache/', |
246
|
|
|
'calculate_response_time' => true, |
247
|
|
|
'create_default_user' => false, |
248
|
|
|
'chartEngine' => 'Jit', |
249
|
|
|
'date_formats' => array( |
250
|
|
|
'Y-m-d' => '2010-12-23', 'm-d-Y' => '12-23-2010', 'd-m-Y' => '23-12-2010', |
251
|
|
|
'Y/m/d' => '2010/12/23', 'm/d/Y' => '12/23/2010', 'd/m/Y' => '23/12/2010', |
252
|
|
|
'Y.m.d' => '2010.12.23', 'd.m.Y' => '23.12.2010', 'm.d.Y' => '12.23.2010', ), |
253
|
|
|
'name_formats' => array( |
254
|
|
|
's f l' => 's f l', 'f l' => 'f l', 's l' => 's l', 'l, s f' => 'l, s f', |
255
|
|
|
'l, f' => 'l, f', 's l, f' => 's l, f', 'l s f' => 'l s f', 'l f s' => 'l f s', |
256
|
|
|
), |
257
|
|
|
'dbconfigoption' => array( |
258
|
|
|
'persistent' => true, |
259
|
|
|
'autofree' => false, |
260
|
|
|
'debug' => 0, |
261
|
|
|
'ssl' => false, ), |
262
|
|
|
'default_action' => 'index', |
263
|
|
|
'default_charset' => return_session_value_or_default('default_charset', |
264
|
|
|
'UTF-8'), |
265
|
|
|
'default_currency_name' => return_session_value_or_default('default_currency_name', 'US Dollar'), |
266
|
|
|
'default_currency_symbol' => return_session_value_or_default('default_currency_symbol', '$'), |
267
|
|
|
'default_currency_iso4217' => return_session_value_or_default('default_currency_iso4217', 'USD'), |
268
|
|
|
'default_currency_significant_digits' => return_session_value_or_default('default_currency_significant_digits', 2), |
269
|
|
|
'default_number_grouping_seperator' => return_session_value_or_default('default_number_grouping_seperator', ','), |
270
|
|
|
'default_decimal_seperator' => return_session_value_or_default('default_decimal_seperator', '.'), |
271
|
|
|
'default_date_format' => 'm/d/Y', |
272
|
|
|
'default_locale_name_format' => 's f l', |
273
|
|
|
'default_export_charset' => 'UTF-8', |
274
|
|
|
'default_language' => return_session_value_or_default('default_language', |
275
|
|
|
'en_us'), |
276
|
|
|
'default_module' => 'Home', |
277
|
|
|
'default_password' => '', |
278
|
|
|
'default_permissions' => array( |
279
|
|
|
'dir_mode' => 02770, |
280
|
|
|
'file_mode' => 0755, |
281
|
|
|
'user' => '', |
282
|
|
|
'group' => '', |
283
|
|
|
), |
284
|
|
|
'default_theme' => return_session_value_or_default('site_default_theme', 'Sugar5'), |
285
|
|
|
'default_time_format' => 'h:ia', |
286
|
|
|
'default_user_is_admin' => false, |
287
|
|
|
'default_user_name' => '', |
288
|
|
|
'disable_export' => false, |
289
|
|
|
'disable_persistent_connections' => return_session_value_or_default('disable_persistent_connections', |
290
|
|
|
'false'), |
291
|
|
|
'display_email_template_variable_chooser' => false, |
292
|
|
|
'display_inbound_email_buttons' => false, |
293
|
|
|
'dump_slow_queries' => false, |
294
|
|
|
'email_address_separator' => ',', // use RFC2368 spec unless we have a noncompliant email client |
295
|
|
|
'email_default_editor' => 'html', |
296
|
|
|
'email_default_client' => 'sugar', |
297
|
|
|
'email_default_delete_attachments' => true, |
298
|
|
|
'history_max_viewed' => 50, |
299
|
|
|
'installer_locked' => true, |
300
|
|
|
'import_max_records_per_file' => 100, |
301
|
|
|
'import_max_records_total_limit' => '', |
302
|
|
|
'languages' => array('en_us' => 'English (US)'), |
303
|
|
|
'large_scale_test' => false, |
304
|
|
|
'list_max_entries_per_page' => 20, |
305
|
|
|
'list_max_entries_per_subpanel' => 10, |
306
|
|
|
'lock_default_user_name' => false, |
307
|
|
|
'log_memory_usage' => false, |
308
|
|
|
'portal_view' => 'single_user', |
309
|
|
|
'resource_management' => array( |
310
|
|
|
'special_query_limit' => 50000, |
311
|
|
|
'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'), |
312
|
|
|
'default_limit' => 1000, |
313
|
|
|
), |
314
|
|
|
'require_accounts' => true, |
315
|
|
|
'rss_cache_time' => return_session_value_or_default('rss_cache_time', |
316
|
|
|
'10800'), |
317
|
|
|
'save_query' => 'all', |
318
|
|
|
'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable |
319
|
|
|
'showThemePicker' => true, |
320
|
|
|
'slow_query_time_msec' => '100', |
321
|
|
|
'sugarbeet' => true, |
322
|
|
|
'time_formats' => array( |
323
|
|
|
'H:i' => '23:00', 'h:ia' => '11:00pm', 'h:iA' => '11:00PM', 'h:i a' => '11:00 pm', 'h:i A' => '11:00 PM', |
324
|
|
|
'H.i' => '23.00', 'h.ia' => '11.00pm', 'h.iA' => '11.00PM', 'h.i a' => '11.00 pm', 'h.i A' => '11.00 PM', ), |
325
|
|
|
'tracker_max_display_length' => 15, |
326
|
|
|
'translation_string_prefix' => return_session_value_or_default('translation_string_prefix', false), |
327
|
|
|
'upload_badext' => array( |
328
|
|
|
'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py', |
329
|
|
|
'asp', 'cfm', 'js', 'vbs', 'html', 'htm', 'phtml', ), |
330
|
|
|
'upload_maxsize' => 30000000, |
331
|
|
|
'import_max_execution_time' => 3600, |
332
|
|
|
// 'use_php_code_json' => returnPhpJsonStatus(), |
333
|
|
|
'verify_client_ip' => true, |
334
|
|
|
'js_custom_version' => '', |
335
|
|
|
'js_lang_version' => 1, |
336
|
|
|
'lead_conv_activity_opt' => 'donothing', |
337
|
|
|
'lock_homepage' => false, |
338
|
|
|
'lock_subpanels' => false, |
339
|
|
|
'max_dashlets_homepage' => '15', |
340
|
|
|
'default_max_tabs' => '7', |
341
|
|
|
'dashlet_display_row_options' => array('1', '3', '5', '10'), |
342
|
|
|
'default_subpanel_tabs' => true, |
343
|
|
|
'default_subpanel_links' => false, |
344
|
|
|
'default_swap_last_viewed' => false, |
345
|
|
|
'default_swap_shortcuts' => false, |
346
|
|
|
'default_navigation_paradigm' => 'gm', |
347
|
|
|
'admin_access_control' => false, |
348
|
|
|
'use_common_ml_dir' => false, |
349
|
|
|
'common_ml_dir' => '', |
350
|
|
|
'vcal_time' => '2', |
351
|
|
|
'calendar' => array( |
352
|
|
|
'default_view' => 'week', |
353
|
|
|
'show_calls_by_default' => true, |
354
|
|
|
'show_tasks_by_default' => true, |
355
|
|
|
'show_completed_by_default' => true, |
356
|
|
|
'editview_width' => 990, |
357
|
|
|
'editview_height' => 485, |
358
|
|
|
'day_timestep' => 15, |
359
|
|
|
'week_timestep' => 30, |
360
|
|
|
'items_draggable' => true, |
361
|
|
|
'items_resizable' => true, |
362
|
|
|
'enable_repeat' => true, |
363
|
|
|
'max_repeat_count' => 1000, |
364
|
|
|
), |
365
|
|
|
'passwordsetting' => empty($passwordsetting) ? array( |
366
|
|
|
'SystemGeneratedPasswordON' => '', |
367
|
|
|
'generatepasswordtmpl' => '', |
368
|
|
|
'lostpasswordtmpl' => '', |
369
|
|
|
'forgotpasswordON' => false, |
370
|
|
|
'linkexpiration' => '1', |
371
|
|
|
'linkexpirationtime' => '30', |
372
|
|
|
'linkexpirationtype' => '1', |
373
|
|
|
'systexpiration' => '0', |
374
|
|
|
'systexpirationtime' => '', |
375
|
|
|
'systexpirationtype' => '0', |
376
|
|
|
'systexpirationlogin' => '', |
377
|
|
|
) : $passwordsetting, |
378
|
|
|
'use_real_names' => true, |
379
|
|
|
|
380
|
|
|
'search_wildcard_infront' => false, |
381
|
|
|
'search_wildcard_char' => '%', |
382
|
|
|
'jobs' => array( |
383
|
|
|
'min_retry_interval' => 30, // 30 seconds minimal job retry |
384
|
|
|
'max_retries' => 5, // how many times to retry the job |
385
|
|
|
'timeout' => 86400, // how long a job may spend as running before being force-failed |
386
|
|
|
), |
387
|
|
|
'cron' => array( |
388
|
|
|
'max_cron_jobs' => 10, // max jobs per cron schedule run |
389
|
|
|
'max_cron_runtime' => 30, // max runtime for cron jobs |
390
|
|
|
'min_cron_interval' => 30, // minimal interval between cron jobs |
391
|
|
|
), |
392
|
|
|
); |
393
|
|
|
|
394
|
|
|
if (!is_object($locale)) { |
395
|
|
|
$locale = new Localization(); |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
$sugar_config_defaults['default_currencies'] = $locale->getDefaultCurrencies(); |
399
|
|
|
|
400
|
|
|
$sugar_config_defaults = sugarArrayMerge($locale->getLocaleConfigDefaults(), $sugar_config_defaults); |
401
|
|
|
|
402
|
|
|
return $sugar_config_defaults; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* @deprecated use SugarView::getMenu() instead |
407
|
|
|
*/ |
408
|
|
|
function load_menu($path) |
409
|
|
|
{ |
410
|
|
|
global $module_menu; |
411
|
|
|
|
412
|
|
|
if (file_exists($path.'Menu.php')) { |
413
|
|
|
require $path.'Menu.php'; |
414
|
|
|
} |
415
|
|
|
if (file_exists('custom/'.$path.'Ext/Menus/menu.ext.php')) { |
416
|
|
|
require 'custom/'.$path.'Ext/Menus/menu.ext.php'; |
417
|
|
|
} |
418
|
|
|
if (file_exists('custom/application/Ext/Menus/menu.ext.php')) { |
419
|
|
|
require 'custom/application/Ext/Menus/menu.ext.php'; |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
return $module_menu; |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* get_notify_template_file |
427
|
|
|
* This function will return the location of the email notifications template to use. |
428
|
|
|
* |
429
|
|
|
* @return string relative file path to email notifications template file |
430
|
|
|
*/ |
431
|
|
|
function get_notify_template_file($language) |
432
|
|
|
{ |
433
|
|
|
/* |
434
|
|
|
* Order of operation: |
435
|
|
|
* 1) custom version of specified language |
436
|
|
|
* 2) stock version of specified language |
437
|
|
|
* 3) custom version of en_us template |
438
|
|
|
* 4) stock en_us template |
439
|
|
|
*/ |
440
|
|
|
|
441
|
|
|
// set $file to the base code template so it's set if none of the conditions pass |
442
|
2 |
|
$file = 'include/language/en_us.notify_template.html'; |
443
|
|
|
|
444
|
2 |
|
if (file_exists("custom/include/language/{$language}.notify_template.html")) { |
445
|
|
|
$file = "custom/include/language/{$language}.notify_template.html"; |
446
|
2 |
|
} elseif (file_exists("include/language/{$language}.notify_template.html")) { |
447
|
2 |
|
$file = "include/language/{$language}.notify_template.html"; |
448
|
|
|
} elseif (file_exists('custom/include/language/en_us.notify_template.html')) { |
449
|
|
|
$file = 'custom/include/language/en_us.notify_template.html'; |
450
|
|
|
} |
451
|
|
|
|
452
|
2 |
|
return $file; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
function sugar_config_union($default, $override) |
456
|
|
|
{ |
457
|
|
|
// a little different then array_merge and array_merge_recursive. we want |
458
|
|
|
// the second array to override the first array if the same value exists, |
459
|
|
|
// otherwise merge the unique keys. it handles arrays of arrays recursively |
460
|
|
|
// might be suitable for a generic array_union |
461
|
|
|
if (!is_array($override)) { |
462
|
|
|
$override = array(); |
463
|
|
|
} |
464
|
|
|
foreach ($default as $key => $value) { |
465
|
|
|
if (!array_key_exists($key, $override)) { |
466
|
|
|
$override[$key] = $value; |
467
|
|
|
} elseif (is_array($key)) { |
468
|
|
|
$override[$key] = sugar_config_union($value, $override[$key]); |
469
|
|
|
} |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
return $override; |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
function make_not_writable($file) |
476
|
|
|
{ |
477
|
|
|
// Returns true if the given file/dir has been made not writable |
478
|
|
|
$ret_val = false; |
479
|
|
|
if (is_file($file) || is_dir($file)) { |
480
|
|
|
if (!is_writable($file)) { |
481
|
|
|
$ret_val = true; |
482
|
|
|
} else { |
483
|
|
|
$original_fileperms = fileperms($file); |
484
|
|
|
|
485
|
|
|
// take away writable permissions |
486
|
|
|
$new_fileperms = $original_fileperms & ~0x0092; |
487
|
|
|
@sugar_chmod($file, $new_fileperms); |
488
|
|
|
|
489
|
|
|
if (!is_writable($file)) { |
490
|
|
|
$ret_val = true; |
491
|
|
|
} |
492
|
|
|
} |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
return $ret_val; |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
/** This function returns the name of the person. |
499
|
|
|
* It currently returns "first last". It should not put the space if either name is not available. |
500
|
|
|
* It should not return errors if either name is not available. |
501
|
|
|
* If no names are present, it will return "" |
502
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
503
|
|
|
* All Rights Reserved. |
504
|
|
|
* Contributor(s): ______________________________________.. |
505
|
|
|
*/ |
506
|
|
|
function return_name($row, $first_column, $last_column) |
507
|
|
|
{ |
508
|
|
|
$first_name = ''; |
509
|
|
|
$last_name = ''; |
510
|
|
|
$full_name = ''; |
511
|
|
|
|
512
|
|
|
if (isset($row[$first_column])) { |
513
|
|
|
$first_name = stripslashes($row[$first_column]); |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
if (isset($row[$last_column])) { |
517
|
|
|
$last_name = stripslashes($row[$last_column]); |
518
|
|
|
} |
519
|
|
|
|
520
|
|
|
$full_name = $first_name; |
521
|
|
|
|
522
|
|
|
// If we have a first name and we have a last name |
523
|
|
|
if ($full_name != '' && $last_name != '') { |
524
|
|
|
// append a space, then the last name |
525
|
|
|
$full_name .= ' '.$last_name; |
526
|
|
|
} // If we have no first name, but we have a last name |
527
|
|
|
elseif ($last_name != '') { |
528
|
|
|
// append the last name without the space. |
529
|
|
|
$full_name .= $last_name; |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
return $full_name; |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
function get_languages() |
536
|
|
|
{ |
537
|
|
|
global $sugar_config; |
538
|
|
|
$lang = $sugar_config['languages']; |
539
|
|
|
if (!empty($sugar_config['disabled_languages'])) { |
540
|
|
|
foreach (explode(',', $sugar_config['disabled_languages']) as $disable) { |
541
|
|
|
unset($lang[$disable]); |
542
|
|
|
} |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
return $lang; |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
function get_all_languages() |
549
|
|
|
{ |
550
|
|
|
global $sugar_config; |
551
|
|
|
|
552
|
|
|
return $sugar_config['languages']; |
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
function get_language_display($key) |
556
|
|
|
{ |
557
|
|
|
global $sugar_config; |
558
|
|
|
|
559
|
|
|
return $sugar_config['languages'][$key]; |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
function get_assigned_user_name($assigned_user_id, $is_group = '') |
563
|
|
|
{ |
564
|
71 |
|
static $saved_user_list = null; |
565
|
|
|
|
566
|
71 |
|
if (empty($saved_user_list)) { |
567
|
1 |
|
$saved_user_list = get_user_array(false, '', '', false, null, $is_group); |
568
|
|
|
} |
569
|
|
|
|
570
|
71 |
|
if (isset($saved_user_list[$assigned_user_id])) { |
571
|
64 |
|
return $saved_user_list[$assigned_user_id]; |
572
|
|
|
} |
573
|
|
|
|
574
|
13 |
|
return ''; |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
/** |
578
|
|
|
* retrieves the user_name column value (login). |
579
|
|
|
* |
580
|
|
|
* @param string id GUID of user |
581
|
|
|
* |
582
|
|
|
* @return string |
583
|
|
|
*/ |
584
|
|
|
function get_user_name($id) |
585
|
|
|
{ |
586
|
|
|
global $db; |
587
|
|
|
|
588
|
|
|
if (empty($db)) { |
589
|
|
|
$db = DBManagerFactory::getInstance(); |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
$q = "SELECT user_name FROM users WHERE id='{$id}'"; |
593
|
|
|
$r = $db->query($q); |
594
|
|
|
$a = $db->fetchByAssoc($r); |
595
|
|
|
|
596
|
|
|
return (empty($a)) ? '' : $a['user_name']; |
597
|
|
|
} |
598
|
|
|
|
599
|
|
|
//TODO Update to use global cache |
600
|
|
|
/** |
601
|
|
|
* get_user_array. |
602
|
|
|
* |
603
|
|
|
* This is a helper function to return an Array of users depending on the parameters passed into the function. |
604
|
|
|
* This function uses the get_register_value function by default to use a caching layer where supported. |
605
|
|
|
* This function has been updated return the array sorted by user preference of name display (bug 62712) |
606
|
|
|
* |
607
|
|
|
* @param bool $add_blank Boolean value to add a blank entry to the array results, true by default |
608
|
|
|
* @param string $status String value indicating the status to filter users by, "Active" by default |
609
|
|
|
* @param string $user_id String value to specify a particular user id value (searches the id column of users table), blank by default |
610
|
|
|
* @param bool $use_real_name Boolean value indicating whether or not results should include the full name or just user_name, false by default |
611
|
|
|
* @param string $user_name_filter String value indicating the user_name filter (searches the user_name column of users table) to optionally search with, blank by default |
612
|
|
|
* @param string $portal_filter String query filter for portal users (defaults to searching non-portal users), change to blank if you wish to search for all users including portal users |
613
|
|
|
* @param bool $from_cache Boolean value indicating whether or not to use the get_register_value function for caching, true by default |
614
|
|
|
* |
615
|
|
|
* @return array Array of users matching the filter criteria that may be from cache (if similar search was previously run) |
616
|
|
|
*/ |
617
|
|
|
function get_user_array($add_blank = true, $status = 'Active', $user_id = '', $use_real_name = false, $user_name_filter = '', $portal_filter = ' AND portal_only=0 ', $from_cache = true) |
618
|
|
|
{ |
619
|
3 |
|
global $locale, $sugar_config, $current_user; |
620
|
|
|
|
621
|
3 |
|
if (empty($locale)) { |
622
|
|
|
$locale = new Localization(); |
623
|
|
|
} |
624
|
|
|
|
625
|
3 |
|
if ($from_cache) { |
626
|
3 |
|
$key_name = $add_blank.$status.$user_id.$use_real_name.$user_name_filter.$portal_filter; |
627
|
3 |
|
$user_array = get_register_value('user_array', $key_name); |
628
|
|
|
} |
629
|
|
|
|
630
|
3 |
|
if (empty($user_array)) { |
631
|
3 |
|
$db = DBManagerFactory::getInstance(); |
632
|
3 |
|
$temp_result = array(); |
633
|
|
|
// Including deleted users for now. |
634
|
3 |
|
if (empty($status)) { |
635
|
1 |
|
$query = 'SELECT id, first_name, last_name, user_name FROM users WHERE 1=1'.$portal_filter; |
636
|
|
|
} else { |
637
|
2 |
|
$query = "SELECT id, first_name, last_name, user_name from users WHERE status='$status'".$portal_filter; |
638
|
|
|
} |
639
|
|
|
/* BEGIN - SECURITY GROUPS */ |
640
|
3 |
|
global $current_user, $sugar_config; |
641
|
3 |
|
if (!is_admin($current_user) |
642
|
3 |
|
&& isset($sugar_config['securitysuite_filter_user_list']) |
643
|
3 |
|
&& $sugar_config['securitysuite_filter_user_list'] == true |
644
|
3 |
|
&& (empty($_REQUEST['module']) || $_REQUEST['module'] != 'Home') |
645
|
3 |
|
&& (empty($_REQUEST['action']) || $_REQUEST['action'] != 'DynamicAction') |
646
|
|
|
) { |
647
|
|
|
require_once 'modules/SecurityGroups/SecurityGroup.php'; |
648
|
|
|
global $current_user; |
649
|
|
|
$group_where = SecurityGroup::getGroupUsersWhere($current_user->id); |
650
|
|
|
$query .= ' AND ('.$group_where.') '; |
651
|
|
|
} |
652
|
|
|
/* END - SECURITY GROUPS */ |
653
|
3 |
|
if (!empty($user_name_filter)) { |
654
|
|
|
$user_name_filter = $db->quote($user_name_filter); |
655
|
|
|
$query .= " AND user_name LIKE '$user_name_filter%' "; |
656
|
|
|
} |
657
|
3 |
|
if (!empty($user_id)) { |
658
|
|
|
$query .= " OR id='{$user_id}'"; |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
//get the user preference for name formatting, to be used in order by |
662
|
3 |
|
$order_by_string = ' user_name ASC '; |
663
|
3 |
|
if (!empty($current_user) && !empty($current_user->id)) { |
664
|
|
|
$formatString = $current_user->getPreference('default_locale_name_format'); |
665
|
|
|
|
666
|
|
|
//create the order by string based on position of first and last name in format string |
667
|
|
|
$order_by_string = ' user_name ASC '; |
668
|
|
|
$firstNamePos = strpos($formatString, 'f'); |
669
|
|
|
$lastNamePos = strpos($formatString, 'l'); |
670
|
|
|
if ($firstNamePos !== false || $lastNamePos !== false) { |
671
|
|
|
//its possible for first name to be skipped, check for this |
672
|
|
|
if ($firstNamePos === false) { |
673
|
|
|
$order_by_string = 'last_name ASC'; |
674
|
|
|
} else { |
675
|
|
|
$order_by_string = ($lastNamePos < $firstNamePos) ? 'last_name, first_name ASC' : 'first_name, last_name ASC'; |
676
|
|
|
} |
677
|
|
|
} |
678
|
|
|
} |
679
|
|
|
|
680
|
3 |
|
$query = $query.' ORDER BY '.$order_by_string; |
681
|
3 |
|
$GLOBALS['log']->debug("get_user_array query: $query"); |
682
|
3 |
|
$result = $db->query($query, true, 'Error filling in user array: '); |
683
|
|
|
|
684
|
3 |
|
if ($add_blank == true) { |
685
|
|
|
// Add in a blank row |
686
|
|
|
$temp_result[''] = ''; |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
// Get the id and the name. |
690
|
3 |
|
while ($row = $db->fetchByAssoc($result)) { |
691
|
2 |
|
if ($use_real_name == true || showFullName()) { |
692
|
2 |
|
if (isset($row['last_name'])) { // cn: we will ALWAYS have both first_name and last_name (empty value if blank in db) |
693
|
2 |
|
$temp_result[$row['id']] = $locale->getLocaleFormattedName($row['first_name'], $row['last_name']); |
694
|
|
|
} else { |
695
|
2 |
|
$temp_result[$row['id']] = $row['user_name']; |
696
|
|
|
} |
697
|
|
|
} else { |
698
|
|
|
$temp_result[$row['id']] = $row['user_name']; |
699
|
|
|
} |
700
|
|
|
} |
701
|
|
|
|
702
|
3 |
|
$user_array = $temp_result; |
703
|
3 |
|
if ($from_cache) { |
704
|
3 |
|
set_register_value('user_array', $key_name, $temp_result); |
705
|
|
|
} |
706
|
|
|
} |
707
|
|
|
|
708
|
3 |
|
return $user_array; |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
/** |
712
|
|
|
* uses a different query to return a list of users than get_user_array() |
713
|
|
|
* Used from QuickSearch.php. |
714
|
|
|
* |
715
|
|
|
* @param args string where clause entry |
716
|
|
|
* |
717
|
|
|
* @return array Array of Users' details that match passed criteria |
718
|
|
|
*/ |
719
|
|
|
function getUserArrayFromFullName($args, $hide_portal_users = false) |
720
|
|
|
{ |
721
|
|
|
global $locale; |
722
|
|
|
$db = DBManagerFactory::getInstance(); |
723
|
|
|
|
724
|
|
|
// jmorais@dri - Bug #51411 |
725
|
|
|
// |
726
|
|
|
// Refactor the code responsible for parsing supplied $args, this way we |
727
|
|
|
// ensure that if $args has at least one space (after trim), the $inClause |
728
|
|
|
// will be composed by several clauses ($inClauses) inside parenthesis. |
729
|
|
|
// |
730
|
|
|
// Ensuring that operator precedence is respected, and avoiding |
731
|
|
|
// inactive/deleted users to be retrieved. |
732
|
|
|
// |
733
|
|
|
$args = trim($args); |
734
|
|
|
if (strpos($args, ' ')) { |
735
|
|
|
$inClauses = array(); |
736
|
|
|
|
737
|
|
|
$argArray = explode(' ', $args); |
738
|
|
|
foreach ($argArray as $arg) { |
739
|
|
|
$arg = $db->quote($arg); |
740
|
|
|
$inClauses[] = "(first_name LIKE '{$arg}%' OR last_name LIKE '{$arg}%')"; |
741
|
|
|
} |
742
|
|
|
|
743
|
|
|
$inClause = '('.implode('OR ', $inClauses).')'; |
744
|
|
|
} else { |
745
|
|
|
$args = $db->quote($args); |
746
|
|
|
$inClause = "(first_name LIKE '{$args}%' OR last_name LIKE '{$args}%')"; |
747
|
|
|
} |
748
|
|
|
// ~jmorais@dri |
749
|
|
|
|
750
|
|
|
$query = "SELECT id, first_name, last_name, user_name FROM users WHERE status='Active' AND deleted=0 AND "; |
751
|
|
|
if ($hide_portal_users) { |
752
|
|
|
$query .= ' portal_only=0 AND '; |
753
|
|
|
} |
754
|
|
|
$query .= $inClause; |
755
|
|
|
/* BEGIN - SECURITY GROUPS */ |
756
|
|
|
global $current_user, $sugar_config; |
757
|
|
|
if (!is_admin($current_user) |
758
|
|
|
&& isset($sugar_config['securitysuite_filter_user_list']) |
759
|
|
|
&& $sugar_config['securitysuite_filter_user_list'] == true |
760
|
|
|
) { |
761
|
|
|
require_once 'modules/SecurityGroups/SecurityGroup.php'; |
762
|
|
|
global $current_user; |
763
|
|
|
$group_where = SecurityGroup::getGroupUsersWhere($current_user->id); |
764
|
|
|
$query .= ' AND ('.$group_where.') '; |
765
|
|
|
} |
766
|
|
|
/* END - SECURITY GROUPS */ |
767
|
|
|
$query .= ' ORDER BY last_name ASC'; |
768
|
|
|
|
769
|
|
|
$r = $db->query($query); |
770
|
|
|
$ret = array(); |
771
|
|
|
while ($a = $db->fetchByAssoc($r)) { |
772
|
|
|
$ret[$a['id']] = $locale->getLocaleFormattedName($a['first_name'], $a['last_name']); |
773
|
|
|
} |
774
|
|
|
|
775
|
|
|
return $ret; |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
/** |
779
|
|
|
* based on user pref then system pref. |
780
|
|
|
*/ |
781
|
|
|
function showFullName() |
782
|
|
|
{ |
783
|
3 |
|
global $sugar_config; |
784
|
3 |
|
global $current_user; |
785
|
3 |
|
static $showFullName = null; |
786
|
|
|
|
787
|
3 |
|
if (is_null($showFullName)) { |
788
|
1 |
|
$sysPref = !empty($sugar_config['use_real_names']); |
789
|
1 |
|
$userPref = (is_object($current_user)) ? $current_user->getPreference('use_real_names') : null; |
790
|
|
|
|
791
|
1 |
|
if ($userPref != null) { |
792
|
1 |
|
$showFullName = ($userPref == 'on'); |
793
|
|
|
} else { |
794
|
|
|
$showFullName = $sysPref; |
795
|
|
|
} |
796
|
|
|
} |
797
|
|
|
|
798
|
3 |
|
return $showFullName; |
799
|
|
|
} |
800
|
|
|
|
801
|
|
|
function clean($string, $maxLength) |
802
|
|
|
{ |
803
|
|
|
$string = substr($string, 0, $maxLength); |
804
|
|
|
|
805
|
|
|
return escapeshellcmd($string); |
806
|
|
|
} |
807
|
|
|
|
808
|
|
|
/** |
809
|
|
|
* Copy the specified request variable to the member variable of the specified object. |
810
|
|
|
* Do no copy if the member variable is already set. |
811
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
812
|
|
|
* All Rights Reserved. |
813
|
|
|
* Contributor(s): ______________________________________.. |
814
|
|
|
*/ |
815
|
|
|
function safe_map($request_var, &$focus, $always_copy = false) |
816
|
|
|
{ |
817
|
|
|
safe_map_named($request_var, $focus, $request_var, $always_copy); |
818
|
|
|
} |
819
|
|
|
|
820
|
|
|
/** |
821
|
|
|
* Copy the specified request variable to the member variable of the specified object. |
822
|
|
|
* Do no copy if the member variable is already set. |
823
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
824
|
|
|
* All Rights Reserved. |
825
|
|
|
* Contributor(s): ______________________________________.. |
826
|
|
|
*/ |
827
|
|
|
function safe_map_named($request_var, &$focus, $member_var, $always_copy) |
828
|
|
|
{ |
829
|
|
|
if (isset($_REQUEST[$request_var]) && ($always_copy || is_null($focus->$member_var))) { |
830
|
|
|
$GLOBALS['log']->debug("safe map named called assigning '{$_REQUEST[$request_var]}' to $member_var"); |
831
|
|
|
$focus->$member_var = $_REQUEST[$request_var]; |
832
|
|
|
} |
833
|
|
|
} |
834
|
|
|
|
835
|
|
|
/** |
836
|
|
|
* This function retrieves an application language file and returns the array of strings included in the $app_list_strings var. |
837
|
|
|
* |
838
|
|
|
* @param string $language specific language to load |
839
|
|
|
* |
840
|
|
|
* @return array lang strings |
841
|
|
|
*/ |
842
|
|
|
function return_app_list_strings_language($language) |
843
|
|
|
{ |
844
|
5 |
|
global $app_list_strings; |
845
|
5 |
|
global $sugar_config; |
846
|
|
|
|
847
|
5 |
|
$cache_key = 'app_list_strings.'.$language; |
848
|
|
|
|
849
|
|
|
// Check for cached value |
850
|
5 |
|
$cache_entry = sugar_cache_retrieve($cache_key); |
851
|
5 |
|
if (!empty($cache_entry)) { |
852
|
5 |
|
return $cache_entry; |
853
|
|
|
} |
854
|
|
|
|
855
|
|
|
$default_language = isset($sugar_config['default_language']) ? $sugar_config['default_language'] : 'en_us'; |
856
|
|
|
$temp_app_list_strings = $app_list_strings; |
857
|
|
|
|
858
|
|
|
$langs = array(); |
859
|
|
|
if ($language != 'en_us') { |
860
|
|
|
$langs[] = 'en_us'; |
861
|
|
|
} |
862
|
|
|
if ($default_language != 'en_us' && $language != $default_language) { |
863
|
|
|
$langs[] = $default_language; |
864
|
|
|
} |
865
|
|
|
$langs[] = $language; |
866
|
|
|
|
867
|
|
|
$app_list_strings_array = array(); |
868
|
|
|
|
869
|
|
|
foreach ($langs as $lang) { |
870
|
|
|
$app_list_strings = array(); |
871
|
|
|
if (file_exists("include/language/$lang.lang.php")) { |
872
|
|
|
include "include/language/$lang.lang.php"; |
873
|
|
|
$GLOBALS['log']->info("Found language file: $lang.lang.php"); |
874
|
|
|
} |
875
|
|
|
if (file_exists("include/language/$lang.lang.override.php")) { |
876
|
|
|
include "include/language/$lang.lang.override.php"; |
877
|
|
|
$GLOBALS['log']->info("Found override language file: $lang.lang.override.php"); |
878
|
|
|
} |
879
|
|
|
if (file_exists("include/language/$lang.lang.php.override")) { |
880
|
|
|
include "include/language/$lang.lang.php.override"; |
881
|
|
|
$GLOBALS['log']->info("Found override language file: $lang.lang.php.override"); |
882
|
|
|
} |
883
|
|
|
|
884
|
|
|
$app_list_strings_array[] = $app_list_strings; |
885
|
|
|
} |
886
|
|
|
|
887
|
|
|
$app_list_strings = array(); |
888
|
|
|
foreach ($app_list_strings_array as $app_list_strings_item) { |
889
|
|
|
$app_list_strings = sugarLangArrayMerge($app_list_strings, $app_list_strings_item); |
890
|
|
|
} |
891
|
|
|
|
892
|
|
|
foreach ($langs as $lang) { |
893
|
|
|
if (file_exists("custom/application/Ext/Language/$lang.lang.ext.php")) { |
894
|
|
|
$app_list_strings = _mergeCustomAppListStrings("custom/application/Ext/Language/$lang.lang.ext.php", $app_list_strings); |
895
|
|
|
$GLOBALS['log']->info("Found extended language file: $lang.lang.ext.php"); |
896
|
|
|
} |
897
|
|
|
if (file_exists("custom/include/language/$lang.lang.php")) { |
898
|
|
|
include "custom/include/language/$lang.lang.php"; |
899
|
|
|
$GLOBALS['log']->info("Found custom language file: $lang.lang.php"); |
900
|
|
|
} |
901
|
|
|
} |
902
|
|
|
|
903
|
|
|
if (!isset($app_list_strings)) { |
904
|
|
|
$GLOBALS['log']->fatal("Unable to load the application language file for the selected language ($language) or the default language ($default_language) or the en_us language"); |
905
|
|
|
|
906
|
|
|
return; |
907
|
|
|
} |
908
|
|
|
|
909
|
|
|
$return_value = $app_list_strings; |
910
|
|
|
$app_list_strings = $temp_app_list_strings; |
911
|
|
|
|
912
|
|
|
sugar_cache_put($cache_key, $return_value); |
913
|
|
|
|
914
|
|
|
return $return_value; |
915
|
|
|
} |
916
|
|
|
|
917
|
|
|
/** |
918
|
|
|
* The dropdown items in custom language files is $app_list_strings['$key']['$second_key'] = $value not |
919
|
|
|
* $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. |
920
|
|
|
* |
921
|
|
|
* @param file string the language that you want include, |
922
|
|
|
* @param app_list_strings array the golbal strings |
923
|
|
|
* |
924
|
|
|
* @return array |
925
|
|
|
*/ |
926
|
|
|
//jchi 25347 |
927
|
|
|
function _mergeCustomAppListStrings($file, $app_list_strings) |
928
|
|
|
{ |
929
|
|
|
$app_list_strings_original = $app_list_strings; |
930
|
|
|
unset($app_list_strings); |
931
|
|
|
// FG - bug 45525 - $exemptDropdown array is defined (once) here, not inside the foreach |
932
|
|
|
// This way, language file can add items to save specific standard codelist from being overwritten |
933
|
|
|
$exemptDropdowns = array(); |
934
|
|
|
include $file; |
935
|
|
|
if (!isset($app_list_strings) || !is_array($app_list_strings)) { |
936
|
|
|
return $app_list_strings_original; |
937
|
|
|
} |
938
|
|
|
//Bug 25347: We should not merge custom dropdown fields unless they relate to parent fields or the module list. |
939
|
|
|
|
940
|
|
|
// FG - bug 45525 - Specific codelists must NOT be overwritten |
941
|
|
|
$exemptDropdowns[] = 'moduleList'; |
942
|
|
|
$exemptDropdowns[] = 'moduleListSingular'; |
943
|
|
|
$exemptDropdowns = array_merge($exemptDropdowns, getTypeDisplayList()); |
944
|
|
|
|
945
|
|
|
foreach ($app_list_strings as $key => $value) { |
946
|
|
|
if (!in_array($key, $exemptDropdowns) && array_key_exists($key, $app_list_strings_original)) { |
947
|
|
|
unset($app_list_strings_original["$key"]); |
948
|
|
|
} |
949
|
|
|
} |
950
|
|
|
$app_list_strings = sugarArrayMergeRecursive($app_list_strings_original, $app_list_strings); |
951
|
|
|
|
952
|
|
|
return $app_list_strings; |
953
|
|
|
} |
954
|
|
|
|
955
|
|
|
/** |
956
|
|
|
* This function retrieves an application language file and returns the array of strings included. |
957
|
|
|
* |
958
|
|
|
* @param string $language specific language to load |
959
|
|
|
* |
960
|
|
|
* @return array lang strings |
961
|
|
|
*/ |
962
|
|
|
function return_application_language($language) |
963
|
|
|
{ |
964
|
4 |
|
global $app_strings, $sugar_config; |
965
|
|
|
|
966
|
4 |
|
$cache_key = 'app_strings.'.$language; |
967
|
|
|
|
968
|
|
|
// Check for cached value |
969
|
4 |
|
$cache_entry = sugar_cache_retrieve($cache_key); |
970
|
4 |
|
if (!empty($cache_entry)) { |
971
|
4 |
|
return $cache_entry; |
972
|
|
|
} |
973
|
|
|
|
974
|
|
|
$temp_app_strings = $app_strings; |
975
|
|
|
$default_language = $sugar_config['default_language']; |
976
|
|
|
|
977
|
|
|
$langs = array(); |
978
|
|
|
if ($language != 'en_us') { |
979
|
|
|
$langs[] = 'en_us'; |
980
|
|
|
} |
981
|
|
|
if ($default_language != 'en_us' && $language != $default_language) { |
982
|
|
|
$langs[] = $default_language; |
983
|
|
|
} |
984
|
|
|
|
985
|
|
|
$langs[] = $language; |
986
|
|
|
|
987
|
|
|
$app_strings_array = array(); |
988
|
|
|
|
989
|
|
|
foreach ($langs as $lang) { |
990
|
|
|
$app_strings = array(); |
991
|
|
|
if (file_exists("include/language/$lang.lang.php")) { |
992
|
|
|
include "include/language/$lang.lang.php"; |
993
|
|
|
$GLOBALS['log']->info("Found language file: $lang.lang.php"); |
994
|
|
|
} |
995
|
|
|
if (file_exists("include/language/$lang.lang.override.php")) { |
996
|
|
|
include "include/language/$lang.lang.override.php"; |
997
|
|
|
$GLOBALS['log']->info("Found override language file: $lang.lang.override.php"); |
998
|
|
|
} |
999
|
|
|
if (file_exists("include/language/$lang.lang.php.override")) { |
1000
|
|
|
include "include/language/$lang.lang.php.override"; |
1001
|
|
|
$GLOBALS['log']->info("Found override language file: $lang.lang.php.override"); |
1002
|
|
|
} |
1003
|
|
|
if (file_exists("custom/application/Ext/Language/$lang.lang.ext.php")) { |
1004
|
|
|
include "custom/application/Ext/Language/$lang.lang.ext.php"; |
1005
|
|
|
$GLOBALS['log']->info("Found extended language file: $lang.lang.ext.php"); |
1006
|
|
|
} |
1007
|
|
|
if (file_exists("custom/include/language/$lang.lang.php")) { |
1008
|
|
|
include "custom/include/language/$lang.lang.php"; |
1009
|
|
|
$GLOBALS['log']->info("Found custom language file: $lang.lang.php"); |
1010
|
|
|
} |
1011
|
|
|
$app_strings_array[] = $app_strings; |
1012
|
|
|
} |
1013
|
|
|
|
1014
|
|
|
$app_strings = array(); |
1015
|
|
|
foreach ($app_strings_array as $app_strings_item) { |
1016
|
|
|
$app_strings = sugarLangArrayMerge($app_strings, $app_strings_item); |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
|
|
if (!isset($app_strings)) { |
1020
|
|
|
$GLOBALS['log']->fatal('Unable to load the application language strings'); |
1021
|
|
|
|
1022
|
|
|
return; |
1023
|
|
|
} |
1024
|
|
|
|
1025
|
|
|
// If we are in debug mode for translating, turn on the prefix now! |
1026
|
|
|
if (!empty($sugar_config['translation_string_prefix'])) { |
1027
|
|
|
foreach ($app_strings as $entry_key => $entry_value) { |
1028
|
|
|
$app_strings[$entry_key] = $language.' '.$entry_value; |
1029
|
|
|
} |
1030
|
|
|
} |
1031
|
|
|
if (isset($_SESSION['show_deleted'])) { |
1032
|
|
|
$app_strings['LBL_DELETE_BUTTON'] = $app_strings['LBL_UNDELETE_BUTTON']; |
1033
|
|
|
$app_strings['LBL_DELETE_BUTTON_LABEL'] = $app_strings['LBL_UNDELETE_BUTTON_LABEL']; |
1034
|
|
|
$app_strings['LBL_DELETE_BUTTON_TITLE'] = $app_strings['LBL_UNDELETE_BUTTON_TITLE']; |
1035
|
|
|
$app_strings['LBL_DELETE'] = $app_strings['LBL_UNDELETE']; |
1036
|
|
|
} |
1037
|
|
|
|
1038
|
|
|
$app_strings['LBL_ALT_HOT_KEY'] = get_alt_hot_key(); |
1039
|
|
|
|
1040
|
|
|
$return_value = $app_strings; |
1041
|
|
|
$app_strings = $temp_app_strings; |
1042
|
|
|
|
1043
|
|
|
sugar_cache_put($cache_key, $return_value); |
1044
|
|
|
|
1045
|
|
|
return $return_value; |
1046
|
|
|
} |
1047
|
|
|
|
1048
|
|
|
/** |
1049
|
|
|
* This function retrieves a module's language file and returns the array of strings included. |
1050
|
|
|
* |
1051
|
|
|
* @param string $language specific language to load |
1052
|
|
|
* @param string $module module name to load strings for |
1053
|
|
|
* @param bool $refresh optional, true if you want to rebuild the language strings |
1054
|
|
|
* |
1055
|
|
|
* @return array lang strings |
1056
|
|
|
*/ |
1057
|
|
|
function return_module_language($language, $module, $refresh = false) |
1058
|
|
|
{ |
1059
|
47 |
|
global $mod_strings; |
1060
|
47 |
|
global $sugar_config; |
1061
|
47 |
|
global $currentModule; |
1062
|
|
|
|
1063
|
|
|
// Jenny - Bug 8119: Need to check if $module is not empty |
1064
|
47 |
|
if (empty($module)) { |
1065
|
|
|
$stack = debug_backtrace(); |
1066
|
|
|
$GLOBALS['log']->warn('Variable module is not in return_module_language '.var_export($stack, true)); |
1067
|
|
|
|
1068
|
|
|
return array(); |
1069
|
|
|
} |
1070
|
|
|
|
1071
|
47 |
|
if (!$refresh) { |
1072
|
47 |
|
$cache_key = LanguageManager::getLanguageCacheKey($module, $language); |
1073
|
|
|
// Check for cached value |
1074
|
47 |
|
$cache_entry = sugar_cache_retrieve($cache_key); |
1075
|
47 |
|
if (!empty($cache_entry) && is_array($cache_entry)) { |
1076
|
40 |
|
return $cache_entry; |
1077
|
|
|
} |
1078
|
|
|
} |
1079
|
|
|
// Store the current mod strings for later |
1080
|
14 |
|
$temp_mod_strings = $mod_strings; |
1081
|
14 |
|
$loaded_mod_strings = array(); |
1082
|
14 |
|
$language_used = $language; |
1083
|
14 |
|
$default_language = $sugar_config['default_language']; |
1084
|
|
|
|
1085
|
14 |
|
if (empty($language)) { |
1086
|
7 |
|
$language = $default_language; |
1087
|
|
|
} |
1088
|
|
|
|
1089
|
|
|
// Bug 21559 - So we can get all the strings defined in the template, refresh |
1090
|
|
|
// the vardefs file if the cached language file doesn't exist. |
1091
|
14 |
|
if (!file_exists(sugar_cached('modules/').$module.'/language/'.$language.'.lang.php') |
1092
|
14 |
|
&& !empty($GLOBALS['beanList'][$module]) |
1093
|
|
|
) { |
1094
|
7 |
|
$object = BeanFactory::getObjectName($module); |
1095
|
7 |
|
VardefManager::refreshVardefs($module, $object); |
1096
|
|
|
} |
1097
|
|
|
|
1098
|
14 |
|
$loaded_mod_strings = LanguageManager::loadModuleLanguage($module, $language, $refresh); |
1099
|
|
|
|
1100
|
|
|
// cn: bug 6048 - merge en_us with requested language |
1101
|
14 |
|
if ($language != $sugar_config['default_language']) { |
1102
|
|
|
$loaded_mod_strings = sugarLangArrayMerge( |
1103
|
|
|
LanguageManager::loadModuleLanguage($module, $sugar_config['default_language'], $refresh), |
1104
|
|
|
$loaded_mod_strings |
1105
|
|
|
); |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
// Load in en_us strings by default |
1109
|
14 |
|
if ($language != 'en_us' && $sugar_config['default_language'] != 'en_us') { |
1110
|
|
|
$loaded_mod_strings = sugarLangArrayMerge( |
1111
|
|
|
LanguageManager::loadModuleLanguage($module, 'en_us', $refresh), |
1112
|
|
|
$loaded_mod_strings |
1113
|
|
|
); |
1114
|
|
|
} |
1115
|
|
|
|
1116
|
|
|
// If we are in debug mode for translating, turn on the prefix now! |
1117
|
14 |
|
if ($sugar_config['translation_string_prefix']) { |
1118
|
|
|
foreach ($loaded_mod_strings as $entry_key => $entry_value) { |
1119
|
|
|
$loaded_mod_strings[$entry_key] = $language_used.' '.$entry_value; |
1120
|
|
|
} |
1121
|
|
|
} |
1122
|
|
|
|
1123
|
14 |
|
$return_value = $loaded_mod_strings; |
1124
|
14 |
|
if (!isset($mod_strings)) { |
1125
|
8 |
|
$mod_strings = $return_value; |
1126
|
|
|
} else { |
1127
|
8 |
|
$mod_strings = $temp_mod_strings; |
1128
|
|
|
} |
1129
|
|
|
|
1130
|
14 |
|
$cache_key = LanguageManager::getLanguageCacheKey($module, $language); |
1131
|
14 |
|
sugar_cache_put($cache_key, $return_value); |
1132
|
|
|
|
1133
|
14 |
|
return $return_value; |
1134
|
|
|
} |
1135
|
|
|
|
1136
|
|
|
/** This function retrieves an application language file and returns the array of strings included in the $mod_list_strings var. |
1137
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1138
|
|
|
* All Rights Reserved. |
1139
|
|
|
* Contributor(s): ______________________________________.. |
1140
|
|
|
* If you are using the current language, do not call this function unless you are loading it for the first time */ |
1141
|
|
|
function return_mod_list_strings_language($language, $module) |
1142
|
|
|
{ |
1143
|
|
|
global $mod_list_strings; |
1144
|
|
|
global $sugar_config; |
1145
|
|
|
global $currentModule; |
1146
|
|
|
|
1147
|
|
|
$cache_key = 'mod_list_str_lang.'.$language.$module; |
1148
|
|
|
|
1149
|
|
|
// Check for cached value |
1150
|
|
|
$cache_entry = sugar_cache_retrieve($cache_key); |
1151
|
|
|
if (!empty($cache_entry)) { |
1152
|
|
|
return $cache_entry; |
1153
|
|
|
} |
1154
|
|
|
|
1155
|
|
|
$language_used = $language; |
1156
|
|
|
$temp_mod_list_strings = $mod_list_strings; |
1157
|
|
|
$default_language = $sugar_config['default_language']; |
1158
|
|
|
|
1159
|
|
|
if ($currentModule == $module && isset($mod_list_strings) && $mod_list_strings != null) { |
1160
|
|
|
return $mod_list_strings; |
1161
|
|
|
} |
1162
|
|
|
|
1163
|
|
|
// cn: bug 6351 - include en_us if file langpack not available |
1164
|
|
|
// cn: bug 6048 - merge en_us with requested language |
1165
|
|
|
include "modules/$module/language/en_us.lang.php"; |
1166
|
|
|
$en_mod_list_strings = array(); |
1167
|
|
|
if ($language_used != $default_language) { |
1168
|
|
|
$en_mod_list_strings = $mod_list_strings; |
1169
|
|
|
} |
1170
|
|
|
|
1171
|
|
|
if (file_exists("modules/$module/language/$language.lang.php")) { |
1172
|
|
|
include "modules/$module/language/$language.lang.php"; |
1173
|
|
|
} |
1174
|
|
|
|
1175
|
|
|
if (file_exists("modules/$module/language/$language.lang.override.php")) { |
1176
|
|
|
include "modules/$module/language/$language.lang.override.php"; |
1177
|
|
|
} |
1178
|
|
|
|
1179
|
|
|
if (file_exists("modules/$module/language/$language.lang.php.override")) { |
1180
|
|
|
echo 'Please Change:<br>'."modules/$module/language/$language.lang.php.override".'<br>to<br>'.'Please Change:<br>'."modules/$module/language/$language.lang.override.php"; |
1181
|
|
|
include "modules/$module/language/$language.lang.php.override"; |
1182
|
|
|
} |
1183
|
|
|
|
1184
|
|
|
// cn: bug 6048 - merge en_us with requested language |
1185
|
|
|
$mod_list_strings = sugarLangArrayMerge($en_mod_list_strings, $mod_list_strings); |
1186
|
|
|
|
1187
|
|
|
// if we still don't have a language pack, then log an error |
1188
|
|
|
if (!isset($mod_list_strings)) { |
1189
|
|
|
$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})"); |
1190
|
|
|
|
1191
|
|
|
return; |
1192
|
|
|
} |
1193
|
|
|
|
1194
|
|
|
$return_value = $mod_list_strings; |
1195
|
|
|
$mod_list_strings = $temp_mod_list_strings; |
1196
|
|
|
|
1197
|
|
|
sugar_cache_put($cache_key, $return_value); |
1198
|
|
|
|
1199
|
|
|
return $return_value; |
1200
|
|
|
} |
1201
|
|
|
|
1202
|
|
|
/** This function retrieves a theme's language file and returns the array of strings included. |
1203
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1204
|
|
|
* All Rights Reserved. |
1205
|
|
|
* Contributor(s): ______________________________________.. |
1206
|
|
|
*/ |
1207
|
|
|
function return_theme_language($language, $theme) |
1208
|
|
|
{ |
1209
|
|
|
global $mod_strings, $sugar_config, $current_language; |
1210
|
|
|
|
1211
|
|
|
$language_used = $language; |
1212
|
|
|
$default_language = $sugar_config['default_language']; |
1213
|
|
|
|
1214
|
|
|
include SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php"; |
1215
|
|
|
if (file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php")) { |
1216
|
|
|
include SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php"; |
1217
|
|
|
} |
1218
|
|
|
if (file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override")) { |
1219
|
|
|
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"; |
1220
|
|
|
include SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override"; |
1221
|
|
|
} |
1222
|
|
|
if (!isset($theme_strings)) { |
1223
|
|
|
$GLOBALS['log']->warn('Unable to find the theme file for language: '.$language.' and theme: '.$theme); |
1224
|
|
|
require SugarThemeRegistry::get($theme)->getFilePath()."/language/$default_language.lang.php"; |
1225
|
|
|
$language_used = $default_language; |
1226
|
|
|
} |
1227
|
|
|
|
1228
|
|
|
if (!isset($theme_strings)) { |
1229
|
|
|
$GLOBALS['log']->fatal("Unable to load the theme($theme) language file for the selected language($language) or the default language($default_language)"); |
1230
|
|
|
|
1231
|
|
|
return; |
1232
|
|
|
} |
1233
|
|
|
|
1234
|
|
|
// If we are in debug mode for translating, turn on the prefix now! |
1235
|
|
|
if ($sugar_config['translation_string_prefix']) { |
1236
|
|
|
foreach ($theme_strings as $entry_key => $entry_value) { |
1237
|
|
|
$theme_strings[$entry_key] = $language_used.' '.$entry_value; |
1238
|
|
|
} |
1239
|
|
|
} |
1240
|
|
|
|
1241
|
|
|
return $theme_strings; |
1242
|
|
|
} |
1243
|
|
|
|
1244
|
|
|
/** If the session variable is defined and is not equal to "" then return it. Otherwise, return the default value. |
1245
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1246
|
|
|
* All Rights Reserved. |
1247
|
|
|
* Contributor(s): ______________________________________.. |
1248
|
|
|
*/ |
1249
|
|
|
function return_session_value_or_default($varname, $default) |
1250
|
|
|
{ |
1251
|
|
|
if (isset($_SESSION[$varname]) && $_SESSION[$varname] != '') { |
1252
|
|
|
return $_SESSION[$varname]; |
1253
|
|
|
} |
1254
|
|
|
|
1255
|
|
|
return $default; |
1256
|
|
|
} |
1257
|
|
|
|
1258
|
|
|
/** |
1259
|
|
|
* Creates an array of where restrictions. These are used to construct a where SQL statement on the query |
1260
|
|
|
* 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. |
1261
|
|
|
* |
1262
|
|
|
* @param &$where_clauses - The array to append the clause to |
1263
|
|
|
* @param $variable_name - The name of the variable to look for an add to the where clause if found |
1264
|
|
|
* @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. |
1265
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1266
|
|
|
* All Rights Reserved. |
1267
|
|
|
* Contributor(s): ______________________________________.. |
1268
|
|
|
*/ |
1269
|
|
|
function append_where_clause(&$where_clauses, $variable_name, $SQL_name = null) |
1270
|
|
|
{ |
1271
|
|
|
if ($SQL_name == null) { |
1272
|
|
|
$SQL_name = $variable_name; |
1273
|
|
|
} |
1274
|
|
|
|
1275
|
|
|
if (isset($_REQUEST[$variable_name]) && $_REQUEST[$variable_name] != '') { |
1276
|
|
|
array_push($where_clauses, "$SQL_name like '".$GLOBALS['db']->quote($_REQUEST[$variable_name])."%'"); |
1277
|
|
|
} |
1278
|
|
|
} |
1279
|
|
|
|
1280
|
|
|
/** |
1281
|
|
|
* Generate the appropriate SQL based on the where clauses. |
1282
|
|
|
* |
1283
|
|
|
* @param $where_clauses - An Array of individual where clauses stored as strings |
1284
|
|
|
* @returns string where_clause - The final SQL where clause to be executed. |
1285
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1286
|
|
|
* All Rights Reserved. |
1287
|
|
|
* Contributor(s): ______________________________________.. |
1288
|
|
|
*/ |
1289
|
|
|
function generate_where_statement($where_clauses) |
1290
|
|
|
{ |
1291
|
|
|
$where = ''; |
1292
|
|
|
foreach ($where_clauses as $clause) { |
1293
|
|
|
if ($where != '') { |
1294
|
|
|
$where .= ' and '; |
1295
|
|
|
} |
1296
|
|
|
$where .= $clause; |
1297
|
|
|
} |
1298
|
|
|
|
1299
|
|
|
$GLOBALS['log']->info("Here is the where clause for the list view: $where"); |
1300
|
|
|
|
1301
|
|
|
return $where; |
1302
|
|
|
} |
1303
|
|
|
|
1304
|
|
|
/** |
1305
|
|
|
* determines if a passed string matches the criteria for a Sugar GUID. |
1306
|
|
|
* |
1307
|
|
|
* @param string $guid |
1308
|
|
|
* |
1309
|
|
|
* @return bool False on failure |
1310
|
|
|
*/ |
1311
|
|
|
function is_guid($guid) |
1312
|
|
|
{ |
1313
|
1 |
|
if (strlen($guid) != 36) { |
1314
|
1 |
|
return false; |
1315
|
|
|
} |
1316
|
|
|
|
1317
|
|
|
if (preg_match("/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/i", $guid)) { |
1318
|
|
|
return true; |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
return true; |
1322
|
|
|
} |
1323
|
|
|
|
1324
|
|
|
/** |
1325
|
|
|
* A temporary method of generating GUIDs of the correct format for our DB. |
1326
|
|
|
* |
1327
|
|
|
* @return string contianing a GUID in the format: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee |
1328
|
|
|
* |
1329
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1330
|
|
|
* All Rights Reserved. |
1331
|
|
|
* Contributor(s): ______________________________________.. |
1332
|
|
|
*/ |
1333
|
|
|
function create_guid() |
1334
|
|
|
{ |
1335
|
73 |
|
$microTime = microtime(); |
1336
|
73 |
|
list($a_dec, $a_sec) = explode(' ', $microTime); |
1337
|
|
|
|
1338
|
73 |
|
$dec_hex = dechex($a_dec * 1000000); |
1339
|
73 |
|
$sec_hex = dechex($a_sec); |
1340
|
|
|
|
1341
|
73 |
|
ensure_length($dec_hex, 5); |
1342
|
73 |
|
ensure_length($sec_hex, 6); |
1343
|
|
|
|
1344
|
73 |
|
$guid = ''; |
1345
|
73 |
|
$guid .= $dec_hex; |
1346
|
73 |
|
$guid .= create_guid_section(3); |
1347
|
73 |
|
$guid .= '-'; |
1348
|
73 |
|
$guid .= create_guid_section(4); |
1349
|
73 |
|
$guid .= '-'; |
1350
|
73 |
|
$guid .= create_guid_section(4); |
1351
|
73 |
|
$guid .= '-'; |
1352
|
73 |
|
$guid .= create_guid_section(4); |
1353
|
73 |
|
$guid .= '-'; |
1354
|
73 |
|
$guid .= $sec_hex; |
1355
|
73 |
|
$guid .= create_guid_section(6); |
1356
|
|
|
|
1357
|
73 |
|
return $guid; |
1358
|
|
|
} |
1359
|
|
|
|
1360
|
|
|
function create_guid_section($characters) |
1361
|
|
|
{ |
1362
|
73 |
|
$return = ''; |
1363
|
73 |
|
for ($i = 0; $i < $characters; ++$i) { |
1364
|
73 |
|
$return .= dechex(mt_rand(0, 15)); |
1365
|
|
|
} |
1366
|
|
|
|
1367
|
73 |
|
return $return; |
1368
|
|
|
} |
1369
|
|
|
|
1370
|
|
|
function ensure_length(&$string, $length) |
1371
|
|
|
{ |
1372
|
73 |
|
$strlen = strlen($string); |
1373
|
73 |
|
if ($strlen < $length) { |
1374
|
7 |
|
$string = str_pad($string, $length, '0'); |
1375
|
73 |
|
} elseif ($strlen > $length) { |
1376
|
73 |
|
$string = substr($string, 0, $length); |
1377
|
|
|
} |
1378
|
73 |
|
} |
1379
|
|
|
|
1380
|
|
|
function microtime_diff($a, $b) |
1381
|
|
|
{ |
1382
|
|
|
list($a_dec, $a_sec) = explode(' ', $a); |
1383
|
|
|
list($b_dec, $b_sec) = explode(' ', $b); |
1384
|
|
|
|
1385
|
|
|
return $b_sec - $a_sec + $b_dec - $a_dec; |
1386
|
|
|
} |
1387
|
|
|
|
1388
|
|
|
// check if Studio is displayed. |
1389
|
|
|
function displayStudioForCurrentUser() |
1390
|
|
|
{ |
1391
|
|
|
global $current_user; |
1392
|
|
|
if ($current_user->isAdmin()) { |
1393
|
|
|
return true; |
1394
|
|
|
} |
1395
|
|
|
|
1396
|
|
|
return true; |
1397
|
|
|
} |
1398
|
|
|
|
1399
|
|
|
function displayWorkflowForCurrentUser() |
1400
|
|
|
{ |
1401
|
|
|
$_SESSION['display_workflow_for_user'] = false; |
1402
|
|
|
|
1403
|
|
|
return false; |
1404
|
|
|
} |
1405
|
|
|
|
1406
|
|
|
// return an array with all modules where the user is an admin. |
1407
|
|
|
function get_admin_modules_for_user($user) |
1408
|
|
|
{ |
1409
|
|
|
$GLOBALS['log']->deprecated('get_admin_modules_for_user() is deprecated as of 6.2.2 and may disappear in the future, use Users->getDeveloperModules() instead'); |
1410
|
|
|
|
1411
|
|
|
if (!isset($user)) { |
1412
|
|
|
$modules = array(); |
1413
|
|
|
|
1414
|
|
|
return $modules; |
1415
|
|
|
} |
1416
|
|
|
|
1417
|
|
|
return $user->getDeveloperModules(); |
1418
|
|
|
} |
1419
|
|
|
|
1420
|
|
|
function get_workflow_admin_modules_for_user($user) |
1421
|
|
|
{ |
1422
|
|
|
if (isset($_SESSION['get_workflow_admin_modules_for_user'])) { |
1423
|
|
|
return $_SESSION['get_workflow_admin_modules_for_user']; |
1424
|
|
|
} |
1425
|
|
|
|
1426
|
|
|
global $moduleList; |
1427
|
|
|
$workflow_mod_list = array(); |
1428
|
|
|
foreach ($moduleList as $module) { |
1429
|
|
|
$workflow_mod_list[$module] = $module; |
1430
|
|
|
} |
1431
|
|
|
|
1432
|
|
|
// This list is taken from teh previous version of workflow_utils.php |
1433
|
|
|
$workflow_mod_list['Tasks'] = 'Tasks'; |
1434
|
|
|
$workflow_mod_list['Calls'] = 'Calls'; |
1435
|
|
|
$workflow_mod_list['Meetings'] = 'Meetings'; |
1436
|
|
|
$workflow_mod_list['Notes'] = 'Notes'; |
1437
|
|
|
$workflow_mod_list['ProjectTask'] = 'Project Tasks'; |
1438
|
|
|
$workflow_mod_list['Leads'] = 'Leads'; |
1439
|
|
|
$workflow_mod_list['Opportunities'] = 'Opportunities'; |
1440
|
|
|
// End of list |
1441
|
|
|
|
1442
|
|
|
$workflow_admin_modules = array(); |
1443
|
|
|
if (empty($user)) { |
1444
|
|
|
return $workflow_admin_modules; |
1445
|
|
|
} |
1446
|
|
|
$actions = ACLAction::getUserActions($user->id); |
1447
|
|
|
//check for ForecastSchedule because it doesn't exist in $workflow_mod_list |
1448
|
|
|
if (isset($actions['ForecastSchedule']['module']['admin']['aclaccess']) && ($actions['ForecastSchedule']['module']['admin']['aclaccess'] == ACL_ALLOW_DEV || |
1449
|
|
|
$actions['ForecastSchedule']['module']['admin']['aclaccess'] == ACL_ALLOW_ADMIN_DEV) |
1450
|
|
|
) { |
1451
|
|
|
$workflow_admin_modules['Forecasts'] = 'Forecasts'; |
1452
|
|
|
} |
1453
|
|
|
foreach ($workflow_mod_list as $key => $val) { |
1454
|
|
|
if (!in_array($val, $workflow_admin_modules) && ($val != 'iFrames' && $val != 'Feeds' && $val != 'Home' && $val != 'Dashboard' |
1455
|
|
|
&& $val != 'Calendar' && $val != 'Activities' && $val != 'Reports') && |
1456
|
|
|
($user->isDeveloperForModule($key)) |
1457
|
|
|
) { |
1458
|
|
|
$workflow_admin_modules[$key] = $val; |
1459
|
|
|
} |
1460
|
|
|
} |
1461
|
|
|
$_SESSION['get_workflow_admin_modules_for_user'] = $workflow_admin_modules; |
1462
|
|
|
|
1463
|
|
|
return $workflow_admin_modules; |
1464
|
|
|
} |
1465
|
|
|
|
1466
|
|
|
// Check if user is admin for at least one module. |
1467
|
|
|
function is_admin_for_any_module($user) |
1468
|
|
|
{ |
1469
|
|
|
if (!isset($user)) { |
1470
|
|
|
return false; |
1471
|
|
|
} |
1472
|
|
|
if ($user->isAdmin()) { |
1473
|
|
|
return true; |
1474
|
|
|
} |
1475
|
|
|
|
1476
|
|
|
return false; |
1477
|
|
|
} |
1478
|
|
|
|
1479
|
|
|
// Check if user is admin for a specific module. |
1480
|
|
|
function is_admin_for_module($user, $module) |
1481
|
|
|
{ |
1482
|
|
|
if (!isset($user)) { |
1483
|
|
|
return false; |
1484
|
|
|
} |
1485
|
|
|
if ($user->isAdmin()) { |
1486
|
|
|
return true; |
1487
|
|
|
} |
1488
|
|
|
|
1489
|
|
|
return false; |
1490
|
|
|
} |
1491
|
|
|
|
1492
|
|
|
/** |
1493
|
|
|
* Check if user id belongs to a system admin. |
1494
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1495
|
|
|
* All Rights Reserved. |
1496
|
|
|
* Contributor(s): ______________________________________.. |
1497
|
|
|
*/ |
1498
|
|
|
function is_admin($user) |
1499
|
|
|
{ |
1500
|
92 |
|
if (empty($user)) { |
1501
|
|
|
return false; |
1502
|
|
|
} |
1503
|
|
|
|
1504
|
92 |
|
return $user->isAdmin(); |
1505
|
|
|
} |
1506
|
|
|
|
1507
|
|
|
/** |
1508
|
|
|
* Return the display name for a theme if it exists. |
1509
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1510
|
|
|
* All Rights Reserved. |
1511
|
|
|
* Contributor(s): ______________________________________.. |
1512
|
|
|
* |
1513
|
|
|
* @deprecated use SugarThemeRegistry::get($theme)->name instead |
1514
|
|
|
*/ |
1515
|
|
|
function get_theme_display($theme) |
1516
|
|
|
{ |
1517
|
|
|
return SugarThemeRegistry::get($theme)->name; |
1518
|
|
|
} |
1519
|
|
|
|
1520
|
|
|
/** |
1521
|
|
|
* Return an array of directory names. |
1522
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1523
|
|
|
* All Rights Reserved. |
1524
|
|
|
* Contributor(s): ______________________________________.. |
1525
|
|
|
* |
1526
|
|
|
* @deprecated use SugarThemeRegistry::availableThemes() instead. |
1527
|
|
|
*/ |
1528
|
|
|
function get_themes() |
1529
|
|
|
{ |
1530
|
|
|
return SugarThemeRegistry::availableThemes(); |
1531
|
|
|
} |
1532
|
|
|
|
1533
|
|
|
/** |
1534
|
|
|
* THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED; USE get_select_options_with_id() |
1535
|
|
|
* Create HTML to display select options in a dropdown list. To be used inside |
1536
|
|
|
* of a select statement in a form. |
1537
|
|
|
* param $option_list - the array of strings to that contains the option list |
1538
|
|
|
* param $selected - the string which contains the default value |
1539
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1540
|
|
|
* All Rights Reserved. |
1541
|
|
|
* Contributor(s): ______________________________________.. |
1542
|
|
|
*/ |
1543
|
|
|
function get_select_options($option_list, $selected) |
1544
|
|
|
{ |
1545
|
|
|
return get_select_options_with_id($option_list, $selected); |
1546
|
|
|
} |
1547
|
|
|
|
1548
|
|
|
/** |
1549
|
|
|
* Create HTML to display select options in a dropdown list. To be used inside |
1550
|
|
|
* 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. |
1551
|
|
|
* param $option_list - the array of strings to that contains the option list |
1552
|
|
|
* param $selected - the string which contains the default value |
1553
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1554
|
|
|
* All Rights Reserved. |
1555
|
|
|
* Contributor(s): ______________________________________.. |
1556
|
|
|
*/ |
1557
|
|
|
function get_select_options_with_id($option_list, $selected_key) |
1558
|
|
|
{ |
1559
|
19 |
|
return get_select_options_with_id_separate_key($option_list, $option_list, $selected_key); |
1560
|
|
|
} |
1561
|
|
|
|
1562
|
|
|
/** |
1563
|
|
|
* Create HTML to display select options in a dropdown list. To be used inside |
1564
|
|
|
* 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. |
1565
|
|
|
* param $label_list - the array of strings to that contains the option list |
1566
|
|
|
* param $key_list - the array of strings to that contains the values list |
1567
|
|
|
* param $selected - the string which contains the default value |
1568
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1569
|
|
|
* All Rights Reserved. |
1570
|
|
|
* Contributor(s): ______________________________________.. |
1571
|
|
|
*/ |
1572
|
|
|
function get_select_options_with_id_separate_key($label_list, $key_list, $selected_key, $massupdate = false) |
1573
|
|
|
{ |
1574
|
20 |
|
global $app_strings; |
1575
|
20 |
|
$select_options = ''; |
1576
|
|
|
|
1577
|
|
|
//for setting null selection values to human readable --None-- |
1578
|
20 |
|
$pattern = "/'0?'></"; |
1579
|
20 |
|
$replacement = "''>".$app_strings['LBL_NONE'].'<'; |
1580
|
20 |
|
if ($massupdate) { |
1581
|
1 |
|
$replacement .= "/OPTION>\n<OPTION value='__SugarMassUpdateClearField__'><"; // Giving the user the option to unset a drop down list. I.e. none means that it won't get updated |
1582
|
|
|
} |
1583
|
|
|
|
1584
|
20 |
|
if (empty($key_list)) { |
1585
|
1 |
|
$key_list = array(); |
1586
|
|
|
} |
1587
|
|
|
//create the type dropdown domain and set the selected value if $opp value already exists |
1588
|
20 |
|
foreach ($key_list as $option_key => $option_value) { |
1589
|
20 |
|
$selected_string = ''; |
1590
|
|
|
// the system is evaluating $selected_key == 0 || '' to true. Be very careful when changing this. Test all cases. |
1591
|
|
|
// The bug was only happening with one of the users in the drop down. It was being replaced by none. |
1592
|
|
|
if ( |
1593
|
20 |
|
($option_key != '' && $selected_key == $option_key) |
1594
|
|
|
|| ( |
1595
|
20 |
|
$option_key == '' |
1596
|
20 |
|
&& (($selected_key == '' && !$massupdate) || $selected_key == '__SugarMassUpdateClearField__') |
1597
|
|
|
) |
1598
|
20 |
|
|| (is_array($selected_key) && in_array($option_key, $selected_key)) |
1599
|
|
|
) { |
1600
|
12 |
|
$selected_string = 'selected '; |
1601
|
|
|
} |
1602
|
|
|
|
1603
|
20 |
|
$html_value = $option_key; |
1604
|
|
|
|
1605
|
20 |
|
$select_options .= "\n<OPTION ".$selected_string."value='$html_value'>$label_list[$option_key]</OPTION>"; |
1606
|
|
|
} |
1607
|
20 |
|
$select_options = preg_replace($pattern, $replacement, $select_options); |
1608
|
|
|
|
1609
|
20 |
|
return $select_options; |
1610
|
|
|
} |
1611
|
|
|
|
1612
|
|
|
/** |
1613
|
|
|
* Call this method instead of die(). |
1614
|
|
|
* We print the error message and then die with an appropriate |
1615
|
|
|
* exit code. |
1616
|
|
|
*/ |
1617
|
|
|
function sugar_die($error_message, $exit_code = 1) |
1618
|
|
|
{ |
1619
|
|
|
global $focus; |
1620
|
|
|
sugar_cleanup(); |
1621
|
|
|
//echo $error_message; |
1622
|
|
|
//die($exit_code); |
1623
|
|
|
throw new \Exception($error_message, $exit_code); |
1624
|
|
|
} |
1625
|
|
|
|
1626
|
|
|
/** |
1627
|
|
|
* Create javascript to clear values of all elements in a form. |
1628
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1629
|
|
|
* All Rights Reserved. |
1630
|
|
|
* Contributor(s): ______________________________________.. |
1631
|
|
|
*/ |
1632
|
|
|
function get_clear_form_js() |
1633
|
|
|
{ |
1634
|
|
|
$the_script = <<<EOQ |
1635
|
|
|
<script type="text/javascript" language="JavaScript"> |
1636
|
|
|
function clear_form(form) { |
1637
|
|
|
var newLoc = 'index.php?action=' + form.action.value + '&module=' + form.module.value + '&query=true&clear_query=true'; |
1638
|
|
|
if(typeof(form.advanced) != 'undefined'){ |
1639
|
|
|
newLoc += '&advanced=' + form.advanced.value; |
1640
|
|
|
} |
1641
|
|
|
document.location.href= newLoc; |
1642
|
|
|
} |
1643
|
|
|
</script> |
1644
|
|
|
EOQ; |
1645
|
|
|
|
1646
|
|
|
return $the_script; |
1647
|
|
|
} |
1648
|
|
|
|
1649
|
|
|
/** |
1650
|
|
|
* Create javascript to set the cursor focus to specific field in a form |
1651
|
|
|
* when the screen is rendered. The field name is currently hardcoded into the |
1652
|
|
|
* the function. |
1653
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1654
|
|
|
* All Rights Reserved. |
1655
|
|
|
* Contributor(s): ______________________________________.. |
1656
|
|
|
*/ |
1657
|
|
|
function get_set_focus_js() |
1658
|
|
|
{ |
1659
|
|
|
//TODO Clint 5/20 - Make this function more generic so that it can take in the target form and field names as variables |
1660
|
|
|
$the_script = <<<EOQ |
1661
|
|
|
<script type="text/javascript" language="JavaScript"> |
1662
|
|
|
<!-- |
1663
|
|
|
function set_focus() { |
1664
|
|
|
if (document.forms.length > 0) { |
1665
|
|
|
for (i = 0; i < document.forms.length; i++) { |
1666
|
|
|
for (j = 0; j < document.forms[i].elements.length; j++) { |
1667
|
|
|
var field = document.forms[i].elements[j]; |
1668
|
|
|
if ((field.type == "text" || field.type == "textarea" || field.type == "password") && |
1669
|
|
|
!field.disabled && (field.name == "first_name" || field.name == "name" || field.name == "user_name" || field.name=="document_name")) { |
1670
|
|
|
field.focus(); |
1671
|
|
|
if (field.type == "text") { |
1672
|
|
|
field.select(); |
1673
|
|
|
} |
1674
|
|
|
break; |
1675
|
|
|
} |
1676
|
|
|
} |
1677
|
|
|
} |
1678
|
|
|
} |
1679
|
|
|
} |
1680
|
|
|
--> |
1681
|
6 |
|
</script> |
1682
|
|
|
EOQ; |
1683
|
|
|
|
1684
|
6 |
|
return $the_script; |
1685
|
|
|
} |
1686
|
|
|
|
1687
|
|
|
/** |
1688
|
|
|
* Very cool algorithm for sorting multi-dimensional arrays. Found at http://us2.php.net/manual/en/function.array-multisort.php |
1689
|
|
|
* Syntax: $new_array = array_csort($array [, 'col1' [, SORT_FLAG [, SORT_FLAG]]]...); |
1690
|
|
|
* Explanation: $array is the array you want to sort, 'col1' is the name of the column |
1691
|
|
|
* you want to sort, SORT_FLAGS are : SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING |
1692
|
|
|
* you can repeat the 'col',FLAG,FLAG, as often you want, the highest prioritiy is given to |
1693
|
|
|
* the first - so the array is sorted by the last given column first, then the one before ... |
1694
|
|
|
* Example: $array = array_csort($array,'town','age',SORT_DESC,'name'); |
1695
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1696
|
|
|
* All Rights Reserved. |
1697
|
|
|
* Contributor(s): ______________________________________.. |
1698
|
|
|
*/ |
1699
|
|
|
function array_csort() |
1700
|
|
|
{ |
1701
|
|
|
$args = func_get_args(); |
1702
|
|
|
$marray = array_shift($args); |
1703
|
|
|
$i = 0; |
1704
|
|
|
|
1705
|
|
|
$msortline = 'return(array_multisort('; |
1706
|
|
|
foreach ($args as $arg) { |
1707
|
|
|
++$i; |
1708
|
|
|
if (is_string($arg)) { |
1709
|
|
|
foreach ($marray as $row) { |
1710
|
|
|
$sortarr[$i][] = $row[$arg]; |
1711
|
|
|
} |
1712
|
|
|
} else { |
1713
|
|
|
$sortarr[$i] = $arg; |
1714
|
|
|
} |
1715
|
|
|
$msortline .= '$sortarr['.$i.'],'; |
1716
|
|
|
} |
1717
|
|
|
$msortline .= '$marray));'; |
1718
|
|
|
|
1719
|
|
|
eval($msortline); |
1720
|
|
|
|
1721
|
|
|
return $marray; |
1722
|
|
|
} |
1723
|
|
|
|
1724
|
|
|
/** |
1725
|
|
|
* Converts localized date format string to jscalendar format |
1726
|
|
|
* Example: $array = array_csort($array,'town','age',SORT_DESC,'name'); |
1727
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. |
1728
|
|
|
* All Rights Reserved. |
1729
|
|
|
* Contributor(s): ______________________________________.. |
1730
|
|
|
*/ |
1731
|
|
|
function parse_calendardate($local_format) |
1732
|
|
|
{ |
1733
|
|
|
preg_match('/\(?([^-]{1})[^-]*-([^-]{1})[^-]*-([^-]{1})[^-]*\)/', $local_format, $matches); |
1734
|
|
|
$calendar_format = '%'.$matches[1].'-%'.$matches[2].'-%'.$matches[3]; |
1735
|
|
|
|
1736
|
|
|
return str_replace(array('y', 'ᅣ1�7', 'a', 'j'), array('Y', 'Y', 'Y', 'd'), $calendar_format); |
1737
|
|
|
} |
1738
|
|
|
|
1739
|
|
|
function translate($string, $mod = '', $selectedValue = '') |
1740
|
|
|
{ |
1741
|
|
|
//$test_start = microtime(); |
1742
|
|
|
//static $mod_strings_results = array(); |
1743
|
37 |
|
if (!empty($mod)) { |
1744
|
27 |
|
global $current_language; |
1745
|
|
|
//Bug 31275 |
1746
|
27 |
|
if (isset($_REQUEST['login_language'])) { |
1747
|
|
|
$current_language = ($_REQUEST['login_language'] == $current_language) ? $current_language : $_REQUEST['login_language']; |
1748
|
|
|
} |
1749
|
27 |
|
$mod_strings = return_module_language($current_language, $mod); |
1750
|
27 |
|
if ($mod == '') { |
1751
|
27 |
|
echo 'Language is <pre>'.$mod_strings.'</pre>'; |
1752
|
|
|
} |
1753
|
|
|
} else { |
1754
|
16 |
|
global $mod_strings; |
1755
|
|
|
} |
1756
|
|
|
|
1757
|
37 |
|
$returnValue = ''; |
1758
|
37 |
|
global $app_strings, $app_list_strings; |
1759
|
|
|
|
1760
|
37 |
|
if (isset($mod_strings[$string])) { |
1761
|
25 |
|
$returnValue = $mod_strings[$string]; |
1762
|
21 |
|
} elseif (isset($app_strings[$string])) { |
1763
|
10 |
|
$returnValue = $app_strings[$string]; |
1764
|
16 |
|
} elseif (isset($app_list_strings[$string])) { |
1765
|
10 |
|
$returnValue = $app_list_strings[$string]; |
1766
|
7 |
|
} elseif (isset($app_list_strings['moduleList']) && isset($app_list_strings['moduleList'][$string])) { |
1767
|
|
|
$returnValue = $app_list_strings['moduleList'][$string]; |
1768
|
|
|
} |
1769
|
|
|
|
1770
|
|
|
//$test_end = microtime(); |
1771
|
|
|
// |
1772
|
|
|
// $mod_strings_results[$mod] = microtime_diff($test_start,$test_end); |
1773
|
|
|
// |
1774
|
|
|
// echo("translate results:"); |
1775
|
|
|
// $total_time = 0; |
1776
|
|
|
// $total_strings = 0; |
1777
|
|
|
// foreach($mod_strings_results as $key=>$value) |
1778
|
|
|
// { |
1779
|
|
|
// echo("Module $key \t\t time $value \t\t<br>"); |
1780
|
|
|
// $total_time += $value; |
1781
|
|
|
// } |
1782
|
|
|
// |
1783
|
|
|
// echo("Total time: $total_time<br>"); |
1784
|
|
|
|
1785
|
37 |
|
if (empty($returnValue)) { |
1786
|
7 |
|
return $string; |
1787
|
|
|
} |
1788
|
|
|
|
1789
|
|
|
// Bug 48996 - Custom enums with '0' value were not returning because of empty check |
1790
|
|
|
// Added a numeric 0 checker to the conditional to allow 0 value indexed to pass |
1791
|
37 |
|
if (is_array($returnValue) && (!empty($selectedValue) || (is_numeric($selectedValue) && $selectedValue == 0)) && isset($returnValue[$selectedValue])) { |
1792
|
2 |
|
return $returnValue[$selectedValue]; |
1793
|
|
|
} |
1794
|
|
|
|
1795
|
37 |
|
return $returnValue; |
1796
|
|
|
} |
1797
|
|
|
|
1798
|
|
|
function unTranslateNum($num) |
1799
|
|
|
{ |
1800
|
|
|
static $dec_sep; |
1801
|
|
|
static $num_grp_sep; |
1802
|
|
|
global $current_user, $sugar_config; |
1803
|
|
|
|
1804
|
|
|
if ($dec_sep == null) { |
1805
|
|
|
$user_dec_sep = $current_user->getPreference('dec_sep'); |
1806
|
|
|
$dec_sep = (empty($user_dec_sep) ? $sugar_config['default_decimal_seperator'] : $user_dec_sep); |
1807
|
|
|
} |
1808
|
|
|
if ($num_grp_sep == null) { |
1809
|
|
|
$user_num_grp_sep = $current_user->getPreference('num_grp_sep'); |
1810
|
|
|
$num_grp_sep = (empty($user_num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $user_num_grp_sep); |
1811
|
|
|
} |
1812
|
|
|
|
1813
|
|
|
$num = preg_replace("'".preg_quote($num_grp_sep)."'", '', $num); |
1814
|
|
|
$num = preg_replace("'".preg_quote($dec_sep)."'", '.', $num); |
1815
|
|
|
|
1816
|
|
|
return $num; |
1817
|
|
|
} |
1818
|
|
|
|
1819
|
|
|
function add_http($url) |
1820
|
|
|
{ |
1821
|
|
|
if (!preg_match('@://@i', $url)) { |
1822
|
|
|
$scheme = 'http'; |
1823
|
|
|
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { |
1824
|
|
|
$scheme = 'https'; |
1825
|
|
|
} |
1826
|
|
|
|
1827
|
|
|
return "{$scheme}://{$url}"; |
1828
|
|
|
} |
1829
|
|
|
|
1830
|
|
|
return $url; |
1831
|
|
|
} |
1832
|
|
|
|
1833
|
|
|
/** |
1834
|
|
|
* returns a default array of XSS tags to clean. |
1835
|
|
|
* |
1836
|
|
|
* @return array |
1837
|
|
|
*/ |
1838
|
|
|
function getDefaultXssTags() |
1839
|
|
|
{ |
1840
|
|
|
$tmp = array( |
1841
|
|
|
'applet' => 'applet', |
1842
|
|
|
'base' => 'base', |
1843
|
|
|
'embed' => 'embed', |
1844
|
|
|
'form' => 'form', |
1845
|
|
|
'frame' => 'frame', |
1846
|
|
|
'frameset' => 'frameset', |
1847
|
|
|
'iframe' => 'iframe', |
1848
|
|
|
'import' => "\?import", |
1849
|
|
|
'layer' => 'layer', |
1850
|
|
|
'link' => 'link', |
1851
|
|
|
'object' => 'object', |
1852
|
|
|
'script' => 'script', |
1853
|
|
|
'xmp' => 'xmp', |
1854
|
|
|
); |
1855
|
|
|
|
1856
|
|
|
$ret = base64_encode(serialize($tmp)); |
1857
|
|
|
|
1858
|
|
|
return $ret; |
1859
|
|
|
} |
1860
|
|
|
|
1861
|
|
|
/** |
1862
|
|
|
* Remove potential xss vectors from strings. |
1863
|
|
|
* |
1864
|
|
|
* @param string str String to search for XSS attack vectors |
1865
|
|
|
* |
1866
|
|
|
* @deprecated |
1867
|
|
|
* |
1868
|
|
|
* @return string |
1869
|
|
|
*/ |
1870
|
|
|
function remove_xss($str) |
1871
|
|
|
{ |
1872
|
|
|
return SugarCleaner::cleanHtml($str, false); |
1873
|
|
|
} |
1874
|
|
|
|
1875
|
|
|
/** |
1876
|
|
|
* Detects typical XSS attack patterns. |
1877
|
|
|
* |
1878
|
|
|
* @deprecated |
1879
|
|
|
* |
1880
|
|
|
* @param string str String to search for XSS attack vectors |
1881
|
|
|
* @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images. |
1882
|
|
|
* |
1883
|
|
|
* @return array Array of matches, empty on clean string |
1884
|
|
|
*/ |
1885
|
|
|
function clean_xss($str, $cleanImg = true) |
1886
|
|
|
{ |
1887
|
|
|
global $sugar_config; |
1888
|
|
|
|
1889
|
|
|
if (empty($sugar_config['email_xss'])) { |
1890
|
|
|
$sugar_config['email_xss'] = getDefaultXssTags(); |
1891
|
|
|
} |
1892
|
|
|
|
1893
|
|
|
$xsstags = unserialize(base64_decode($sugar_config['email_xss'])); |
1894
|
|
|
|
1895
|
|
|
// cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.) |
1896
|
|
|
$jsEvents = 'onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|'; |
1897
|
|
|
$jsEvents .= 'onmouseup|onmouseover|onmousedown|onmouseenter|onmouseleave|onmousemove|onload|onchange|'; |
1898
|
|
|
$jsEvents .= 'onreset|onselect|onsubmit|onkeydown|onkeypress|onkeyup|onabort|onerror|ondragdrop'; |
1899
|
|
|
|
1900
|
|
|
$attribute_regex = "#\b({$jsEvents})\s*=\s*(?|(?!['\"])\S+|['\"].+?['\"])#sim"; |
1901
|
|
|
$javascript_regex = '@<[^/>][^>]+(expression\(|j\W*a\W*v\W*a|v\W*b\W*s\W*c\W*r|&#|/\*|\*/)[^>]*>@sim'; |
1902
|
|
|
$imgsrc_regex = '#<[^>]+src[^=]*=([^>]*?http(s)?://[^>]*)>#sim'; |
1903
|
|
|
$css_url = '#url\(.*\.\w+\)#'; |
1904
|
|
|
|
1905
|
|
|
$tagsrex = '#<\/?(\w+)((?:\s+(?:\w|\w[\w-]*\w)(?:\s*=\s*(?:\".*?\"|\'.*?\'|[^\'\">\s]+))?)+\s*|\s*)\/?>#im'; |
1906
|
|
|
|
1907
|
|
|
$tagmatches = array(); |
1908
|
|
|
$matches = array(); |
1909
|
|
|
preg_match_all($tagsrex, $str, $tagmatches, PREG_PATTERN_ORDER); |
1910
|
|
|
foreach ($tagmatches[1] as $no => $tag) { |
1911
|
|
|
if (in_array($tag, $xsstags)) { |
1912
|
|
|
// dangerous tag - take out whole |
1913
|
|
|
$matches[] = $tagmatches[0][$no]; |
1914
|
|
|
continue; |
1915
|
|
|
} |
1916
|
|
|
$attrmatch = array(); |
1917
|
|
|
preg_match_all($attribute_regex, $tagmatches[2][$no], $attrmatch, PREG_PATTERN_ORDER); |
1918
|
|
|
if (!empty($attrmatch[0])) { |
1919
|
|
|
$matches = array_merge($matches, $attrmatch[0]); |
1920
|
|
|
} |
1921
|
|
|
} |
1922
|
|
|
|
1923
|
|
|
$matches = array_merge($matches, xss_check_pattern($javascript_regex, $str)); |
1924
|
|
|
|
1925
|
|
|
if ($cleanImg) { |
1926
|
|
|
$matches = array_merge($matches, |
1927
|
|
|
xss_check_pattern($imgsrc_regex, $str) |
1928
|
|
|
); |
1929
|
|
|
} |
1930
|
|
|
|
1931
|
|
|
// cn: bug 13498 - custom white-list of allowed domains that vet remote images |
1932
|
|
|
preg_match_all($css_url, $str, $cssUrlMatches, PREG_PATTERN_ORDER); |
1933
|
|
|
|
1934
|
|
|
if (isset($sugar_config['security_trusted_domains']) && !empty($sugar_config['security_trusted_domains']) && is_array($sugar_config['security_trusted_domains'])) { |
1935
|
|
|
if (is_array($cssUrlMatches) && count($cssUrlMatches) > 0) { |
1936
|
|
|
// normalize whitelist |
1937
|
|
|
foreach ($sugar_config['security_trusted_domains'] as $k => $v) { |
1938
|
|
|
$sugar_config['security_trusted_domains'][$k] = strtolower($v); |
1939
|
|
|
} |
1940
|
|
|
|
1941
|
|
|
foreach ($cssUrlMatches[0] as $match) { |
1942
|
|
|
$domain = strtolower(substr(strstr($match, '://'), 3)); |
1943
|
|
|
$baseUrl = substr($domain, 0, strpos($domain, '/')); |
1944
|
|
|
|
1945
|
|
|
if (!in_array($baseUrl, $sugar_config['security_trusted_domains'])) { |
1946
|
|
|
$matches[] = $match; |
1947
|
|
|
} |
1948
|
|
|
} |
1949
|
|
|
} |
1950
|
|
|
} else { |
1951
|
|
|
$matches = array_merge($matches, $cssUrlMatches[0]); |
1952
|
|
|
} |
1953
|
|
|
|
1954
|
|
|
return $matches; |
1955
|
|
|
} |
1956
|
|
|
|
1957
|
|
|
/** |
1958
|
|
|
* Helper function used by clean_xss() to parse for known-bad vectors. |
1959
|
|
|
* |
1960
|
|
|
* @param string pattern Regex pattern to use |
1961
|
|
|
* @param string str String to parse for badness |
1962
|
|
|
* |
1963
|
|
|
* @return array |
1964
|
|
|
*/ |
1965
|
|
|
function xss_check_pattern($pattern, $str) |
1966
|
|
|
{ |
1967
|
|
|
preg_match_all($pattern, $str, $matches, PREG_PATTERN_ORDER); |
1968
|
|
|
|
1969
|
|
|
return $matches[1]; |
1970
|
|
|
} |
1971
|
|
|
|
1972
|
|
|
/** |
1973
|
|
|
* Designed to take a string passed in the URL as a parameter and clean all "bad" data from it. |
1974
|
|
|
* |
1975
|
|
|
* @param string $str |
1976
|
|
|
* @param string $filter which corresponds to a regular expression to use; choices are: |
1977
|
|
|
* "STANDARD" ( default ) |
1978
|
|
|
* "STANDARDSPACE" |
1979
|
|
|
* "FILE" |
1980
|
|
|
* "NUMBER" |
1981
|
|
|
* "SQL_COLUMN_LIST" |
1982
|
|
|
* "PATH_NO_URL" |
1983
|
|
|
* "SAFED_GET" |
1984
|
|
|
* "UNIFIED_SEARCH" |
1985
|
|
|
* "AUTO_INCREMENT" |
1986
|
|
|
* "ALPHANUM" |
1987
|
|
|
* @param bool $dieOnBadData true (default) if you want to die if bad data if found, false if not |
1988
|
|
|
*/ |
1989
|
|
|
function clean_string($str, $filter = 'STANDARD', $dieOnBadData = true) |
1990
|
|
|
{ |
1991
|
|
|
global $sugar_config; |
1992
|
|
|
|
1993
|
|
|
$filters = array( |
1994
|
|
|
'STANDARD' => '#[^A-Z0-9\-_\.\@]#i', |
1995
|
|
|
'STANDARDSPACE' => '#[^A-Z0-9\-_\.\@\ ]#i', |
1996
|
|
|
'FILE' => '#[^A-Z0-9\-_\.]#i', |
1997
|
|
|
'NUMBER' => '#[^0-9\-]#i', |
1998
|
|
|
'SQL_COLUMN_LIST' => '#[^A-Z0-9\(\),_\.]#i', |
1999
|
|
|
'PATH_NO_URL' => '#://#i', |
2000
|
|
|
'SAFED_GET' => '#[^A-Z0-9\@\=\&\?\.\/\-_~+]#i', /* range of allowed characters in a GET string */ |
2001
|
|
|
'UNIFIED_SEARCH' => '#[\\x00]#', /* cn: bug 3356 & 9236 - MBCS search strings */ |
2002
|
|
|
'AUTO_INCREMENT' => '#[^0-9\-,\ ]#i', |
2003
|
|
|
'ALPHANUM' => '#[^A-Z0-9\-]#i', |
2004
|
|
|
); |
2005
|
|
|
|
2006
|
|
|
if (preg_match($filters[$filter], $str)) { |
2007
|
|
|
if (isset($GLOBALS['log']) && is_object($GLOBALS['log'])) { |
2008
|
|
|
$GLOBALS['log']->fatal("SECURITY[$filter]: bad data passed in; string: {$str}"); |
2009
|
|
|
} |
2010
|
|
|
if ($dieOnBadData) { |
2011
|
|
|
die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>"); |
2012
|
|
|
} |
2013
|
|
|
|
2014
|
|
|
return false; |
2015
|
|
|
} else { |
2016
|
|
|
return $str; |
2017
|
|
|
} |
2018
|
|
|
} |
2019
|
|
|
|
2020
|
|
|
function clean_special_arguments() |
2021
|
|
|
{ |
2022
|
|
|
if (isset($_SERVER['PHP_SELF'])) { |
2023
|
|
|
if (!empty($_SERVER['PHP_SELF'])) { |
2024
|
|
|
clean_string($_SERVER['PHP_SELF'], 'SAFED_GET'); |
2025
|
|
|
} |
2026
|
|
|
} |
2027
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['login_theme'])) { |
2028
|
|
|
clean_string($_REQUEST['login_theme'], 'STANDARD'); |
2029
|
|
|
} |
2030
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['login_module'])) { |
2031
|
|
|
clean_string($_REQUEST['login_module'], 'STANDARD'); |
2032
|
|
|
} |
2033
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['login_action'])) { |
2034
|
|
|
clean_string($_REQUEST['login_action'], 'STANDARD'); |
2035
|
|
|
} |
2036
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['ck_login_theme_20'])) { |
2037
|
|
|
clean_string($_REQUEST['ck_login_theme_20'], 'STANDARD'); |
2038
|
|
|
} |
2039
|
|
|
if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_theme'])) { |
2040
|
|
|
clean_string($_SESSION['authenticated_user_theme'], 'STANDARD'); |
2041
|
|
|
} |
2042
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['module_name'])) { |
2043
|
|
|
clean_string($_REQUEST['module_name'], 'STANDARD'); |
2044
|
|
|
} |
2045
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['module'])) { |
2046
|
|
|
clean_string($_REQUEST['module'], 'STANDARD'); |
2047
|
|
|
} |
2048
|
|
|
if (!empty($_POST) && !empty($_POST['parent_type'])) { |
2049
|
|
|
clean_string($_POST['parent_type'], 'STANDARD'); |
2050
|
|
|
} |
2051
|
|
|
if (!empty($_REQUEST) && !empty($_REQUEST['mod_lang'])) { |
2052
|
|
|
clean_string($_REQUEST['mod_lang'], 'STANDARD'); |
2053
|
|
|
} |
2054
|
|
|
if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_language'])) { |
2055
|
|
|
clean_string($_SESSION['authenticated_user_language'], 'STANDARD'); |
2056
|
|
|
} |
2057
|
|
|
if (!empty($_SESSION) && !empty($_SESSION['dyn_layout_file'])) { |
2058
|
|
|
clean_string($_SESSION['dyn_layout_file'], 'PATH_NO_URL'); |
2059
|
|
|
} |
2060
|
|
|
if (!empty($_GET) && !empty($_GET['from'])) { |
2061
|
|
|
clean_string($_GET['from']); |
2062
|
|
|
} |
2063
|
|
|
if (!empty($_GET) && !empty($_GET['gmto'])) { |
2064
|
|
|
clean_string($_GET['gmto'], 'NUMBER'); |
2065
|
|
|
} |
2066
|
|
|
if (!empty($_GET) && !empty($_GET['case_number'])) { |
2067
|
|
|
clean_string($_GET['case_number'], 'AUTO_INCREMENT'); |
2068
|
|
|
} |
2069
|
|
|
if (!empty($_GET) && !empty($_GET['bug_number'])) { |
2070
|
|
|
clean_string($_GET['bug_number'], 'AUTO_INCREMENT'); |
2071
|
|
|
} |
2072
|
|
|
if (!empty($_GET) && !empty($_GET['quote_num'])) { |
2073
|
|
|
clean_string($_GET['quote_num'], 'AUTO_INCREMENT'); |
2074
|
|
|
} |
2075
|
|
|
clean_superglobals('stamp', 'ALPHANUM'); // for vcr controls |
2076
|
|
|
clean_superglobals('offset', 'ALPHANUM'); |
2077
|
|
|
clean_superglobals('return_action'); |
2078
|
|
|
clean_superglobals('return_module'); |
2079
|
|
|
|
2080
|
|
|
return true; |
2081
|
|
|
} |
2082
|
|
|
|
2083
|
|
|
/** |
2084
|
|
|
* cleans the given key in superglobals $_GET, $_POST, $_REQUEST. |
2085
|
|
|
*/ |
2086
|
|
|
function clean_superglobals($key, $filter = 'STANDARD') |
2087
|
|
|
{ |
2088
|
|
|
if (isset($_GET[$key])) { |
2089
|
|
|
clean_string($_GET[$key], $filter); |
2090
|
|
|
} |
2091
|
|
|
if (isset($_POST[$key])) { |
2092
|
|
|
clean_string($_POST[$key], $filter); |
2093
|
|
|
} |
2094
|
|
|
if (isset($_REQUEST[$key])) { |
2095
|
|
|
clean_string($_REQUEST[$key], $filter); |
2096
|
|
|
} |
2097
|
|
|
} |
2098
|
|
|
|
2099
|
|
|
function set_superglobals($key, $val) |
2100
|
|
|
{ |
2101
|
|
|
$_GET[$key] = $val; |
2102
|
|
|
$_POST[$key] = $val; |
2103
|
|
|
$_REQUEST[$key] = $val; |
2104
|
|
|
} |
2105
|
|
|
|
2106
|
|
|
// Works in conjunction with clean_string() to defeat SQL injection, file inclusion attacks, and XSS |
2107
|
|
|
function clean_incoming_data() |
2108
|
|
|
{ |
2109
|
|
|
global $sugar_config; |
2110
|
|
|
global $RAW_REQUEST; |
2111
|
|
|
|
2112
|
|
|
if (get_magic_quotes_gpc()) { |
2113
|
|
|
// magic quotes screw up data, we'd have to clean up |
2114
|
|
|
$RAW_REQUEST = array_map('cleanup_slashes', $_REQUEST); |
2115
|
|
|
} else { |
2116
|
|
|
$RAW_REQUEST = $_REQUEST; |
2117
|
|
|
} |
2118
|
|
|
|
2119
|
|
|
if (get_magic_quotes_gpc() == 1) { |
2120
|
|
|
$req = array_map('preprocess_param', $_REQUEST); |
2121
|
|
|
$post = array_map('preprocess_param', $_POST); |
2122
|
|
|
$get = array_map('preprocess_param', $_GET); |
2123
|
|
|
} else { |
2124
|
|
|
$req = array_map('securexss', $_REQUEST); |
2125
|
|
|
$post = array_map('securexss', $_POST); |
2126
|
|
|
$get = array_map('securexss', $_GET); |
2127
|
|
|
} |
2128
|
|
|
|
2129
|
|
|
// PHP cannot stomp out superglobals reliably |
2130
|
|
|
foreach ($post as $k => $v) { |
2131
|
|
|
$_POST[$k] = $v; |
2132
|
|
|
} |
2133
|
|
|
foreach ($get as $k => $v) { |
2134
|
|
|
$_GET[$k] = $v; |
2135
|
|
|
} |
2136
|
|
|
foreach ($req as $k => $v) { |
2137
|
|
|
$_REQUEST[$k] = $v; |
2138
|
|
|
|
2139
|
|
|
//ensure the keys are safe as well. If mbstring encoding translation is on, the post keys don't |
2140
|
|
|
//get translated, so scrub the data but don't die |
2141
|
|
|
if (ini_get('mbstring.encoding_translation') === '1') { |
2142
|
|
|
securexsskey($k, false); |
2143
|
|
|
} else { |
2144
|
|
|
securexsskey($k, true); |
2145
|
|
|
} |
2146
|
|
|
} |
2147
|
|
|
// Any additional variables that need to be cleaned should be added here |
2148
|
|
|
if (isset($_REQUEST['login_theme'])) { |
2149
|
|
|
clean_string($_REQUEST['login_theme']); |
2150
|
|
|
} |
2151
|
|
|
if (isset($_REQUEST['login_module'])) { |
2152
|
|
|
clean_string($_REQUEST['login_module']); |
2153
|
|
|
} |
2154
|
|
|
if (isset($_REQUEST['login_action'])) { |
2155
|
|
|
clean_string($_REQUEST['login_action']); |
2156
|
|
|
} |
2157
|
|
|
if (isset($_REQUEST['login_language'])) { |
2158
|
|
|
clean_string($_REQUEST['login_language']); |
2159
|
|
|
} |
2160
|
|
|
if (isset($_REQUEST['action'])) { |
2161
|
|
|
clean_string($_REQUEST['action']); |
2162
|
|
|
} |
2163
|
|
|
if (isset($_REQUEST['module'])) { |
2164
|
|
|
clean_string($_REQUEST['module']); |
2165
|
|
|
} |
2166
|
|
|
if (isset($_REQUEST['record'])) { |
2167
|
|
|
clean_string($_REQUEST['record'], 'STANDARDSPACE'); |
2168
|
|
|
} |
2169
|
|
|
if (isset($_SESSION['authenticated_user_theme'])) { |
2170
|
|
|
clean_string($_SESSION['authenticated_user_theme']); |
2171
|
|
|
} |
2172
|
|
|
if (isset($_SESSION['authenticated_user_language'])) { |
2173
|
|
|
clean_string($_SESSION['authenticated_user_language']); |
2174
|
|
|
} |
2175
|
|
|
if (isset($_REQUEST['language'])) { |
2176
|
|
|
clean_string($_REQUEST['language']); |
2177
|
|
|
} |
2178
|
|
|
if (isset($sugar_config['default_theme'])) { |
2179
|
|
|
clean_string($sugar_config['default_theme']); |
2180
|
|
|
} |
2181
|
|
|
if (isset($_REQUEST['offset'])) { |
2182
|
|
|
clean_string($_REQUEST['offset']); |
2183
|
|
|
} |
2184
|
|
|
if (isset($_REQUEST['stamp'])) { |
2185
|
|
|
clean_string($_REQUEST['stamp']); |
2186
|
|
|
} |
2187
|
|
|
|
2188
|
|
|
if (isset($_REQUEST['lvso'])) { |
2189
|
|
|
set_superglobals('lvso', (strtolower($_REQUEST['lvso']) === 'desc') ? 'desc' : 'asc'); |
2190
|
|
|
} |
2191
|
|
|
// Clean "offset" and "order_by" parameters in URL |
2192
|
|
|
foreach ($_REQUEST as $key => $val) { |
2193
|
|
|
if (str_end($key, '_offset')) { |
2194
|
|
|
clean_string($_REQUEST[$key], 'ALPHANUM'); // keep this ALPHANUM for disable_count_query |
2195
|
|
|
set_superglobals($key, $_REQUEST[$key]); |
2196
|
|
|
} elseif (str_end($key, '_ORDER_BY')) { |
2197
|
|
|
clean_string($_REQUEST[$key], 'SQL_COLUMN_LIST'); |
2198
|
|
|
set_superglobals($key, $_REQUEST[$key]); |
2199
|
|
|
} |
2200
|
|
|
} |
2201
|
|
|
|
2202
|
|
|
return 0; |
2203
|
|
|
} |
2204
|
|
|
|
2205
|
|
|
// Returns TRUE if $str begins with $begin |
2206
|
|
|
function str_begin($str, $begin) |
2207
|
|
|
{ |
2208
|
99 |
|
return substr($str, 0, strlen($begin)) == $begin; |
2209
|
|
|
} |
2210
|
|
|
|
2211
|
|
|
// Returns TRUE if $str ends with $end |
2212
|
|
|
function str_end($str, $end) |
2213
|
|
|
{ |
2214
|
|
|
return substr($str, strlen($str) - strlen($end)) == $end; |
2215
|
|
|
} |
2216
|
|
|
|
2217
|
|
|
function securexss($value) |
2218
|
|
|
{ |
2219
|
1 |
|
if (is_array($value)) { |
2220
|
|
|
$new = array(); |
2221
|
|
|
foreach ($value as $key => $val) { |
2222
|
|
|
$new[$key] = securexss($val); |
2223
|
|
|
} |
2224
|
|
|
|
2225
|
|
|
return $new; |
2226
|
|
|
} |
2227
|
1 |
|
static $xss_cleanup = array('"' => '&', '"' => '"', "'" => ''', '<' => '<', '>' => '>'); |
2228
|
1 |
|
$value = preg_replace(array('/javascript:/i', '/\0/'), array('java script:', ''), $value); |
2229
|
1 |
|
$value = preg_replace('/javascript:/i', 'java script:', $value); |
2230
|
|
|
|
2231
|
1 |
|
return str_replace(array_keys($xss_cleanup), array_values($xss_cleanup), $value); |
2232
|
|
|
} |
2233
|
|
|
|
2234
|
|
|
function securexsskey($value, $die = true) |
2235
|
|
|
{ |
2236
|
|
|
global $sugar_config; |
2237
|
|
|
$matches = array(); |
2238
|
|
|
preg_match('/[\'"<>]/', $value, $matches); |
2239
|
|
|
if (!empty($matches)) { |
2240
|
|
|
if ($die) { |
2241
|
|
|
die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>"); |
2242
|
|
|
} else { |
2243
|
|
|
unset($_REQUEST[$value]); |
2244
|
|
|
unset($_POST[$value]); |
2245
|
|
|
unset($_GET[$value]); |
2246
|
|
|
} |
2247
|
|
|
} |
2248
|
|
|
} |
2249
|
|
|
|
2250
|
|
|
function preprocess_param($value) |
2251
|
|
|
{ |
2252
|
|
|
if (is_string($value)) { |
2253
|
|
|
if (get_magic_quotes_gpc() == 1) { |
2254
|
|
|
$value = stripslashes($value); |
2255
|
|
|
} |
2256
|
|
|
|
2257
|
|
|
$value = securexss($value); |
2258
|
|
|
} elseif (is_array($value)) { |
2259
|
|
|
foreach ($value as $key => $element) { |
2260
|
|
|
$value[$key] = preprocess_param($element); |
2261
|
|
|
} |
2262
|
|
|
} |
2263
|
|
|
|
2264
|
|
|
return $value; |
2265
|
|
|
} |
2266
|
|
|
|
2267
|
|
|
function cleanup_slashes($value) |
2268
|
|
|
{ |
2269
|
|
|
if (is_string($value)) { |
2270
|
|
|
return stripslashes($value); |
2271
|
|
|
} |
2272
|
|
|
|
2273
|
|
|
return $value; |
2274
|
|
|
} |
2275
|
|
|
|
2276
|
|
|
function set_register_value($category, $name, $value) |
2277
|
|
|
{ |
2278
|
4 |
|
return sugar_cache_put("{$category}:{$name}", $value); |
2279
|
|
|
} |
2280
|
|
|
|
2281
|
|
|
function get_register_value($category, $name) |
2282
|
|
|
{ |
2283
|
4 |
|
return sugar_cache_retrieve("{$category}:{$name}"); |
2284
|
|
|
} |
2285
|
|
|
|
2286
|
|
|
function clear_register_value($category, $name) |
2287
|
|
|
{ |
2288
|
|
|
return sugar_cache_clear("{$category}:{$name}"); |
2289
|
|
|
} |
2290
|
|
|
|
2291
|
|
|
// this function cleans id's when being imported |
2292
|
|
|
function convert_id($string) |
2293
|
|
|
{ |
2294
|
|
|
return preg_replace_callback('|[^A-Za-z0-9\-]|', |
2295
|
|
|
create_function( |
2296
|
|
|
// single quotes are essential here, |
2297
|
|
|
// or alternative escape all $ as \$ |
2298
|
|
|
'$matches', |
2299
|
|
|
'return ord($matches[0]);' |
2300
|
|
|
), $string); |
2301
|
|
|
} |
2302
|
|
|
|
2303
|
|
|
/** |
2304
|
|
|
* @deprecated use SugarTheme::getImage() |
2305
|
|
|
*/ |
2306
|
|
|
function get_image($image, $other_attributes, $width = '', $height = '', $ext = '.gif', $alt = '') |
2307
|
|
|
{ |
2308
|
|
|
return SugarThemeRegistry::current()->getImage(basename($image), $other_attributes, empty($width) ? null : $width, empty($height) ? null : $height, $ext, $alt); |
2309
|
|
|
} |
2310
|
|
|
|
2311
|
|
|
/** |
2312
|
|
|
* @deprecated use SugarTheme::getImageURL() |
2313
|
|
|
*/ |
2314
|
|
|
function getImagePath($image_name) |
2315
|
|
|
{ |
2316
|
|
|
return SugarThemeRegistry::current()->getImageURL($image_name); |
2317
|
|
|
} |
2318
|
|
|
|
2319
|
|
|
function getWebPath($relative_path) |
2320
|
|
|
{ |
2321
|
|
|
//if it has a :// then it isn't a relative path |
2322
|
|
|
if (substr_count($relative_path, '://') > 0) { |
2323
|
|
|
return $relative_path; |
2324
|
|
|
} |
2325
|
|
|
if (defined('TEMPLATE_URL')) { |
2326
|
|
|
$relative_path = SugarTemplateUtilities::getWebPath($relative_path); |
2327
|
|
|
} |
2328
|
|
|
|
2329
|
|
|
return $relative_path; |
2330
|
|
|
} |
2331
|
|
|
|
2332
|
|
|
function getVersionedPath($path, $additional_attrs = '') |
2333
|
|
|
{ |
2334
|
211 |
|
if (empty($GLOBALS['sugar_config']['js_custom_version'])) { |
2335
|
|
|
$GLOBALS['sugar_config']['js_custom_version'] = 1; |
2336
|
|
|
} |
2337
|
211 |
|
$js_version_key = isset($GLOBALS['js_version_key']) ? $GLOBALS['js_version_key'] : ''; |
2338
|
211 |
|
if (inDeveloperMode()) { |
2339
|
|
|
static $rand; |
2340
|
|
|
if (empty($rand)) { |
2341
|
|
|
$rand = mt_rand(); |
2342
|
|
|
} |
2343
|
|
|
$dev = $rand; |
2344
|
|
|
} else { |
2345
|
211 |
|
$dev = ''; |
2346
|
|
|
} |
2347
|
211 |
|
if (is_array($additional_attrs)) { |
2348
|
|
|
$additional_attrs = implode('|', $additional_attrs); |
2349
|
|
|
} |
2350
|
|
|
// cutting 2 last chars here because since md5 is 32 chars, it's always == |
2351
|
211 |
|
$str = substr(base64_encode(md5("$js_version_key|{$GLOBALS['sugar_config']['js_custom_version']}|$dev|$additional_attrs", true)), 0, -2); |
2352
|
|
|
// remove / - it confuses some parsers |
2353
|
211 |
|
$str = strtr($str, '/+', '-_'); |
2354
|
211 |
|
if (empty($path)) { |
2355
|
198 |
|
return $str; |
2356
|
|
|
} |
2357
|
|
|
|
2358
|
28 |
|
return $path."?v=$str"; |
2359
|
|
|
} |
2360
|
|
|
|
2361
|
|
|
function getVersionedScript($path, $additional_attrs = '') |
2362
|
|
|
{ |
2363
|
5 |
|
return '<script type="text/javascript" src="'.getVersionedPath($path, $additional_attrs).'"></script>'; |
2364
|
|
|
} |
2365
|
|
|
|
2366
|
|
|
function getJSPath($relative_path, $additional_attrs = '') |
2367
|
|
|
{ |
2368
|
27 |
|
if (defined('TEMPLATE_URL')) { |
2369
|
|
|
$relative_path = SugarTemplateUtilities::getWebPath($relative_path); |
2370
|
|
|
} |
2371
|
|
|
|
2372
|
27 |
|
return getVersionedPath($relative_path).(!empty($additional_attrs) ? "&$additional_attrs" : ''); |
2373
|
|
|
} |
2374
|
|
|
|
2375
|
|
|
function getSWFPath($relative_path, $additional_params = '') |
2376
|
|
|
{ |
2377
|
|
|
$path = $relative_path; |
2378
|
|
|
if (!empty($additional_params)) { |
2379
|
|
|
$path .= '?'.$additional_params; |
2380
|
|
|
} |
2381
|
|
|
if (defined('TEMPLATE_URL')) { |
2382
|
|
|
$path = TEMPLATE_URL.'/'.$path; |
2383
|
|
|
} |
2384
|
|
|
|
2385
|
|
|
return $path; |
2386
|
|
|
} |
2387
|
|
|
|
2388
|
|
|
function getSQLDate($date_str) |
2389
|
|
|
{ |
2390
|
|
|
if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/', $date_str, $match)) { |
2391
|
|
|
if (strlen($match[2]) == 1) { |
2392
|
|
|
$match[2] = '0'.$match[2]; |
2393
|
|
|
} |
2394
|
|
|
if (strlen($match[1]) == 1) { |
2395
|
|
|
$match[1] = '0'.$match[1]; |
2396
|
|
|
} |
2397
|
|
|
|
2398
|
|
|
return "{$match[3]}-{$match[1]}-{$match[2]}"; |
2399
|
|
|
} elseif (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $date_str, $match)) { |
2400
|
|
|
if (strlen($match[2]) == 1) { |
2401
|
|
|
$match[2] = '0'.$match[2]; |
2402
|
|
|
} |
2403
|
|
|
if (strlen($match[1]) == 1) { |
2404
|
|
|
$match[1] = '0'.$match[1]; |
2405
|
|
|
} |
2406
|
|
|
|
2407
|
|
|
return "{$match[3]}-{$match[1]}-{$match[2]}"; |
2408
|
|
|
} else { |
2409
|
|
|
return ''; |
2410
|
|
|
} |
2411
|
|
|
} |
2412
|
|
|
|
2413
|
|
|
function clone_history(&$db, $from_id, $to_id, $to_type) |
2414
|
|
|
{ |
2415
|
|
|
global $timedate; |
2416
|
|
|
$old_note_id = null; |
2417
|
|
|
$old_filename = null; |
2418
|
|
|
require_once 'include/upload_file.php'; |
2419
|
|
|
$tables = array('calls' => 'Call', 'meetings' => 'Meeting', 'notes' => 'Note', 'tasks' => 'Task'); |
2420
|
|
|
|
2421
|
|
|
$location = array('Email' => 'modules/Emails/Email.php', |
2422
|
|
|
'Call' => 'modules/Calls/Call.php', |
2423
|
|
|
'Meeting' => 'modules/Meetings/Meeting.php', |
2424
|
|
|
'Note' => 'modules/Notes/Note.php', |
2425
|
|
|
'Tasks' => 'modules/Tasks/Task.php', |
2426
|
|
|
); |
2427
|
|
|
|
2428
|
|
|
foreach ($tables as $table => $bean_class) { |
2429
|
|
|
if (!class_exists($bean_class)) { |
2430
|
|
|
require_once $location[$bean_class]; |
2431
|
|
|
} |
2432
|
|
|
|
2433
|
|
|
$bProcessingNotes = false; |
2434
|
|
|
if ($table == 'notes') { |
2435
|
|
|
$bProcessingNotes = true; |
2436
|
|
|
} |
2437
|
|
|
$query = "SELECT id FROM $table WHERE parent_id='$from_id'"; |
2438
|
|
|
$results = $db->query($query); |
2439
|
|
|
while ($row = $db->fetchByAssoc($results)) { |
2440
|
|
|
//retrieve existing record. |
2441
|
|
|
$bean = new $bean_class(); |
2442
|
|
|
$bean->retrieve($row['id']); |
2443
|
|
|
//process for new instance. |
2444
|
|
|
if ($bProcessingNotes) { |
2445
|
|
|
$old_note_id = $row['id']; |
2446
|
|
|
$old_filename = $bean->filename; |
2447
|
|
|
} |
2448
|
|
|
$bean->id = null; |
2449
|
|
|
$bean->parent_id = $to_id; |
2450
|
|
|
$bean->parent_type = $to_type; |
2451
|
|
|
if ($to_type == 'Contacts' and in_array('contact_id', $bean->column_fields)) { |
2452
|
|
|
$bean->contact_id = $to_id; |
2453
|
|
|
} |
2454
|
|
|
$bean->update_date_modified = false; |
2455
|
|
|
$bean->update_modified_by = false; |
2456
|
|
|
if (isset($bean->date_modified)) { |
2457
|
|
|
$bean->date_modified = $timedate->to_db($bean->date_modified); |
2458
|
|
|
} |
2459
|
|
|
if (isset($bean->date_entered)) { |
2460
|
|
|
$bean->date_entered = $timedate->to_db($bean->date_entered); |
2461
|
|
|
} |
2462
|
|
|
//save |
2463
|
|
|
$new_id = $bean->save(); |
2464
|
|
|
|
2465
|
|
|
//duplicate the file now. for notes. |
2466
|
|
|
if ($bProcessingNotes && !empty($old_filename)) { |
2467
|
|
|
UploadFile::duplicate_file($old_note_id, $new_id, $old_filename); |
2468
|
|
|
} |
2469
|
|
|
//reset the values needed for attachment duplication. |
2470
|
|
|
$old_note_id = null; |
2471
|
|
|
$old_filename = null; |
2472
|
|
|
} |
2473
|
|
|
} |
2474
|
|
|
} |
2475
|
|
|
|
2476
|
|
|
function values_to_keys($array) |
2477
|
|
|
{ |
2478
|
|
|
$new_array = array(); |
2479
|
|
|
if (!is_array($array)) { |
2480
|
|
|
return $new_array; |
2481
|
|
|
} |
2482
|
|
|
foreach ($array as $arr) { |
2483
|
|
|
$new_array[$arr] = $arr; |
2484
|
|
|
} |
2485
|
|
|
|
2486
|
|
|
return $new_array; |
2487
|
|
|
} |
2488
|
|
|
|
2489
|
|
|
function clone_relationship(&$db, $tables = array(), $from_column, $from_id, $to_id) |
2490
|
|
|
{ |
2491
|
|
|
foreach ($tables as $table) { |
2492
|
|
|
if ($table == 'emails_beans') { |
2493
|
|
|
$query = "SELECT * FROM $table WHERE $from_column='$from_id' and bean_module='Leads'"; |
2494
|
|
|
} else { |
2495
|
|
|
$query = "SELECT * FROM $table WHERE $from_column='$from_id'"; |
2496
|
|
|
} |
2497
|
|
|
$results = $db->query($query); |
2498
|
|
|
while ($row = $db->fetchByAssoc($results)) { |
2499
|
|
|
$query = "INSERT INTO $table "; |
2500
|
|
|
$names = ''; |
2501
|
|
|
$values = ''; |
2502
|
|
|
$row[$from_column] = $to_id; |
2503
|
|
|
$row['id'] = create_guid(); |
2504
|
|
|
if ($table == 'emails_beans') { |
2505
|
|
|
$row['bean_module'] == 'Contacts'; |
2506
|
|
|
} |
2507
|
|
|
|
2508
|
|
|
foreach ($row as $name => $value) { |
2509
|
|
|
if (empty($names)) { |
2510
|
|
|
$names .= $name; |
2511
|
|
|
$values .= "'$value'"; |
2512
|
|
|
} else { |
2513
|
|
|
$names .= ', '.$name; |
2514
|
|
|
$values .= ", '$value'"; |
2515
|
|
|
} |
2516
|
|
|
} |
2517
|
|
|
$query .= "($names) VALUES ($values)"; |
2518
|
|
|
$db->query($query); |
2519
|
|
|
} |
2520
|
|
|
} |
2521
|
|
|
} |
2522
|
|
|
|
2523
|
|
|
function get_unlinked_email_query($type, $bean) |
2524
|
|
|
{ |
2525
|
4 |
|
global $current_user; |
2526
|
|
|
|
2527
|
4 |
|
$return_array['select'] = 'SELECT emails.id '; |
2528
|
4 |
|
$return_array['from'] = 'FROM emails '; |
2529
|
4 |
|
$return_array['where'] = ''; |
2530
|
4 |
|
$return_array['join'] = " JOIN (select DISTINCT email_id from emails_email_addr_rel eear |
2531
|
|
|
|
2532
|
4 |
|
join email_addr_bean_rel eabr on eabr.bean_id ='$bean->id' and eabr.bean_module = '$bean->module_dir' and |
2533
|
|
|
eabr.email_address_id = eear.email_address_id and eabr.deleted=0 |
2534
|
|
|
where eear.deleted=0 and eear.email_id not in |
2535
|
4 |
|
(select eb.email_id from emails_beans eb where eb.bean_module ='$bean->module_dir' and eb.bean_id = '$bean->id') |
2536
|
4 |
|
) derivedemails on derivedemails.email_id = emails.id"; |
2537
|
4 |
|
$return_array['join_tables'][0] = ''; |
2538
|
|
|
|
2539
|
4 |
|
if (isset($type) and !empty($type['return_as_array'])) { |
2540
|
1 |
|
return $return_array; |
2541
|
|
|
} |
2542
|
|
|
|
2543
|
4 |
|
return $return_array['select'].$return_array['from'].$return_array['where'].$return_array['join']; |
2544
|
|
|
} // fn |
2545
|
|
|
|
2546
|
|
|
function get_emails_by_assign_or_link($params) |
2547
|
|
|
{ |
2548
|
|
|
$relation = $params['link']; |
2549
|
|
|
$bean = $GLOBALS['app']->controller->bean; |
2550
|
|
|
if (empty($bean->$relation)) { |
2551
|
|
|
$bean->load_relationship($relation); |
2552
|
|
|
} |
2553
|
|
|
if (empty($bean->$relation)) { |
2554
|
|
|
$GLOBALS['log']->error("Bad relation '$relation' for bean '{$bean->object_name}' id '{$bean->id}'"); |
2555
|
|
|
|
2556
|
|
|
return array(); |
2557
|
|
|
} |
2558
|
|
|
$rel_module = $bean->$relation->getRelatedModuleName(); |
2559
|
|
|
$rel_join = $bean->$relation->getJoin(array( |
2560
|
|
|
'join_table_alias' => 'link_bean', |
2561
|
|
|
'join_table_link_alias' => 'linkt', |
2562
|
|
|
)); |
2563
|
|
|
$rel_join = str_replace("{$bean->table_name}.id", "'{$bean->id}'", $rel_join); |
2564
|
|
|
$return_array['select'] = 'SELECT DISTINCT emails.id '; |
2565
|
|
|
$return_array['from'] = 'FROM emails '; |
2566
|
|
|
|
2567
|
|
|
$return_array['join'] = array(); |
2568
|
|
|
|
2569
|
|
|
// directly assigned emails |
2570
|
|
|
$return_array['join'][] = " |
2571
|
|
|
SELECT |
2572
|
|
|
eb.email_id, |
2573
|
|
|
'direct' source |
2574
|
|
|
FROM |
2575
|
|
|
emails_beans eb |
2576
|
|
|
WHERE |
2577
|
|
|
eb.bean_module = '{$bean->module_dir}' |
2578
|
|
|
AND eb.bean_id = '{$bean->id}' |
2579
|
|
|
AND eb.deleted=0 |
2580
|
|
|
"; |
2581
|
|
|
|
2582
|
|
|
// Related by directly by email |
2583
|
|
|
$return_array['join'][] = " |
2584
|
|
|
SELECT DISTINCT |
2585
|
|
|
eear.email_id, |
2586
|
|
|
'relate' source |
2587
|
|
|
FROM |
2588
|
|
|
emails_email_addr_rel eear |
2589
|
|
|
INNER JOIN |
2590
|
|
|
email_addr_bean_rel eabr |
2591
|
|
|
ON |
2592
|
|
|
eabr.bean_id ='{$bean->id}' |
2593
|
|
|
AND eabr.bean_module = '{$bean->module_dir}' |
2594
|
|
|
AND eabr.email_address_id = eear.email_address_id |
2595
|
|
|
AND eabr.deleted=0 |
2596
|
|
|
WHERE |
2597
|
|
|
eear.deleted=0 |
2598
|
|
|
"; |
2599
|
|
|
|
2600
|
|
|
$showEmailsOfRelatedContacts = empty($bean->field_defs[$relation]['hide_history_contacts_emails']); |
2601
|
|
|
if (!empty($GLOBALS['sugar_config']['hide_history_contacts_emails']) && isset($GLOBALS['sugar_config']['hide_history_contacts_emails'][$bean->module_name])) { |
2602
|
|
|
$showEmailsOfRelatedContacts = empty($GLOBALS['sugar_config']['hide_history_contacts_emails'][$bean->module_name]); |
2603
|
|
|
} |
2604
|
|
|
if ($showEmailsOfRelatedContacts) { |
2605
|
|
|
// Assigned to contacts |
2606
|
|
|
$return_array['join'][] = " |
2607
|
|
|
SELECT DISTINCT |
2608
|
|
|
eb.email_id, |
2609
|
|
|
'contact' source |
2610
|
|
|
FROM |
2611
|
|
|
emails_beans eb |
2612
|
|
|
$rel_join AND link_bean.id = eb.bean_id |
2613
|
|
|
WHERE |
2614
|
|
|
eb.bean_module = '$rel_module' |
2615
|
|
|
AND eb.deleted=0 |
2616
|
|
|
"; |
2617
|
|
|
// Related by email to linked contact |
2618
|
|
|
$return_array['join'][] = " |
2619
|
|
|
SELECT DISTINCT |
2620
|
|
|
eear.email_id, |
2621
|
|
|
'relate_contact' source |
2622
|
|
|
FROM |
2623
|
|
|
emails_email_addr_rel eear |
2624
|
|
|
INNER JOIN |
2625
|
|
|
email_addr_bean_rel eabr |
2626
|
|
|
ON |
2627
|
|
|
eabr.email_address_id=eear.email_address_id |
2628
|
|
|
AND eabr.bean_module = '$rel_module' |
2629
|
|
|
AND eabr.deleted=0 |
2630
|
|
|
$rel_join AND link_bean.id = eabr.bean_id |
2631
|
|
|
WHERE |
2632
|
|
|
eear.deleted=0 |
2633
|
|
|
"; |
2634
|
|
|
} |
2635
|
|
|
|
2636
|
|
|
$return_array['join'] = ' INNER JOIN ('.implode(' UNION ', $return_array['join']).') email_ids ON emails.id=email_ids.email_id '; |
2637
|
|
|
|
2638
|
|
|
$return_array['where'] = ' WHERE emails.deleted=0 '; |
2639
|
|
|
|
2640
|
|
|
//$return_array['join'] = ''; |
2641
|
|
|
$return_array['join_tables'][0] = ''; |
2642
|
|
|
|
2643
|
|
|
if ($bean->object_name == 'Case' && !empty($bean->case_number)) { |
2644
|
|
|
$where = str_replace('%1', $bean->case_number, $bean->getEmailSubjectMacro()); |
2645
|
|
|
$return_array['where'] .= "\n AND (email_ids.source = 'direct' OR emails.name LIKE '%$where%')"; |
2646
|
|
|
} |
2647
|
|
|
|
2648
|
|
|
return $return_array; |
2649
|
|
|
} |
2650
|
|
|
|
2651
|
|
|
/** |
2652
|
|
|
* Check to see if the number is empty or non-zero. |
2653
|
|
|
* |
2654
|
|
|
* @param $value |
2655
|
|
|
* |
2656
|
|
|
* @return bool |
2657
|
|
|
**/ |
2658
|
|
|
function number_empty($value) |
2659
|
|
|
{ |
2660
|
8 |
|
return empty($value) && $value != '0'; |
2661
|
|
|
} |
2662
|
|
|
|
2663
|
|
|
function get_bean_select_array($add_blank = true, $bean_name, $display_columns, $where = '', $order_by = '', $blank_is_none = false) |
2664
|
|
|
{ |
2665
|
1 |
|
global $beanFiles; |
2666
|
1 |
|
require_once $beanFiles[$bean_name]; |
2667
|
1 |
|
$focus = new $bean_name(); |
2668
|
1 |
|
$user_array = array(); |
2669
|
|
|
|
2670
|
1 |
|
$key = ($bean_name == 'EmailTemplate') ? $bean_name : $bean_name.$display_columns.$where.$order_by; |
2671
|
1 |
|
$user_array = get_register_value('select_array', $key); |
2672
|
1 |
|
if (!$user_array) { |
2673
|
1 |
|
$db = DBManagerFactory::getInstance(); |
2674
|
|
|
|
2675
|
1 |
|
$temp_result = array(); |
2676
|
1 |
|
$query = "SELECT {$focus->table_name}.id, {$display_columns} as display from {$focus->table_name} "; |
2677
|
1 |
|
$query .= 'where '; |
2678
|
1 |
|
if ($where != '') { |
2679
|
|
|
$query .= $where.' AND '; |
2680
|
|
|
} |
2681
|
|
|
|
2682
|
1 |
|
$query .= " {$focus->table_name}.deleted=0"; |
2683
|
|
|
|
2684
|
|
|
/* BEGIN - SECURITY GROUPS */ |
2685
|
1 |
|
global $current_user, $sugar_config; |
2686
|
1 |
|
if ($focus->module_dir == 'Users' && !is_admin($current_user) |
2687
|
1 |
|
&& isset($sugar_config['securitysuite_filter_user_list']) |
2688
|
1 |
|
&& $sugar_config['securitysuite_filter_user_list'] == true |
2689
|
|
|
) { |
2690
|
|
|
require_once 'modules/SecurityGroups/SecurityGroup.php'; |
2691
|
|
|
$group_where = SecurityGroup::getGroupUsersWhere($current_user->id); |
2692
|
|
|
$query .= ' AND ('.$group_where.') '; |
2693
|
1 |
|
} elseif ($focus->bean_implements('ACL') && ACLController::requireSecurityGroup($focus->module_dir, 'list')) { |
2694
|
|
|
require_once 'modules/SecurityGroups/SecurityGroup.php'; |
2695
|
|
|
$owner_where = $focus->getOwnerWhere($current_user->id); |
2696
|
|
|
$group_where = SecurityGroup::getGroupWhere($focus->table_name, $focus->module_dir, $current_user->id); |
2697
|
|
|
if (!empty($owner_where)) { |
2698
|
|
|
$query .= ' AND ('.$owner_where.' or '.$group_where.') '; |
2699
|
|
|
} else { |
2700
|
|
|
$query .= ' AND '.$group_where; |
2701
|
|
|
} |
2702
|
|
|
} |
2703
|
|
|
/* END - SECURITY GROUPS */ |
2704
|
|
|
|
2705
|
1 |
|
if ($order_by != '') { |
2706
|
|
|
$query .= " order by {$focus->table_name}.{$order_by}"; |
2707
|
|
|
} |
2708
|
|
|
|
2709
|
1 |
|
$GLOBALS['log']->debug("get_user_array query: $query"); |
2710
|
1 |
|
$result = $db->query($query, true, 'Error filling in user array: '); |
2711
|
|
|
|
2712
|
1 |
|
if ($add_blank == true) { |
2713
|
|
|
// Add in a blank row |
2714
|
1 |
|
if ($blank_is_none == true) { // set 'blank row' to "--None--" |
2715
|
|
|
global $app_strings; |
2716
|
|
|
$temp_result[''] = $app_strings['LBL_NONE']; |
2717
|
|
|
} else { |
2718
|
1 |
|
$temp_result[''] = ''; |
2719
|
|
|
} |
2720
|
|
|
} |
2721
|
|
|
|
2722
|
|
|
// Get the id and the name. |
2723
|
1 |
|
while ($row = $db->fetchByAssoc($result)) { |
2724
|
1 |
|
$temp_result[$row['id']] = $row['display']; |
2725
|
|
|
} |
2726
|
|
|
|
2727
|
1 |
|
$user_array = $temp_result; |
2728
|
1 |
|
set_register_value('select_array', $key, $temp_result); |
2729
|
|
|
} |
2730
|
|
|
|
2731
|
1 |
|
return $user_array; |
2732
|
|
|
} |
2733
|
|
|
|
2734
|
|
|
/** |
2735
|
|
|
* @param unknown_type $listArray |
2736
|
|
|
*/ |
2737
|
|
|
// function parse_list_modules |
2738
|
|
|
// searches a list for items in a user's allowed tabs and returns an array that removes unallowed tabs from list |
2739
|
|
|
function parse_list_modules(&$listArray) |
2740
|
|
|
{ |
2741
|
|
|
global $modListHeader; |
2742
|
|
|
$returnArray = array(); |
2743
|
|
|
|
2744
|
|
|
foreach ($listArray as $optionName => $optionVal) { |
2745
|
|
|
if (array_key_exists($optionName, $modListHeader)) { |
2746
|
|
|
$returnArray[$optionName] = $optionVal; |
2747
|
|
|
} |
2748
|
|
|
|
2749
|
|
|
// special case for projects |
2750
|
|
|
if (array_key_exists('Project', $modListHeader)) { |
2751
|
|
|
$returnArray['ProjectTask'] = $listArray['ProjectTask']; |
2752
|
|
|
} |
2753
|
|
|
} |
2754
|
|
|
$acldenied = ACLController::disabledModuleList($listArray, false); |
2755
|
|
|
foreach ($acldenied as $denied) { |
2756
|
|
|
unset($returnArray[$denied]); |
2757
|
|
|
} |
2758
|
|
|
asort($returnArray); |
2759
|
|
|
|
2760
|
|
|
return $returnArray; |
2761
|
|
|
} |
2762
|
|
|
|
2763
|
|
|
function display_notice($msg = false) |
2764
|
|
|
{ |
2765
|
|
|
global $error_notice; |
2766
|
|
|
//no error notice - lets just display the error to the user |
2767
|
|
|
if (!isset($error_notice)) { |
2768
|
|
|
echo '<br>'.$msg.'<br>'; |
2769
|
|
|
} else { |
2770
|
|
|
$error_notice .= $msg.'<br>'; |
2771
|
|
|
} |
2772
|
|
|
} |
2773
|
|
|
|
2774
|
|
|
/* checks if it is a number that at least has the plus at the beginning. |
2775
|
|
|
*/ |
2776
|
|
|
function skype_formatted($number) |
2777
|
|
|
{ |
2778
|
|
|
//kbrill - BUG #15375 |
2779
|
|
|
if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'Popup') { |
2780
|
|
|
return false; |
2781
|
|
|
} else { |
2782
|
|
|
return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 3) == '011'; |
2783
|
|
|
} |
2784
|
|
|
// return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 2) == '011'; |
2785
|
|
|
} |
2786
|
|
|
|
2787
|
|
|
function format_skype($number) |
2788
|
|
|
{ |
2789
|
|
|
return preg_replace('/[^\+0-9]/', '', $number); |
2790
|
|
|
} |
2791
|
|
|
|
2792
|
|
|
function insert_charset_header() |
2793
|
|
|
{ |
2794
|
1 |
|
header('Content-Type: text/html; charset=UTF-8'); |
2795
|
|
|
} |
2796
|
|
|
|
2797
|
|
|
function getCurrentURL() |
2798
|
|
|
{ |
2799
|
|
|
$href = 'http:'; |
2800
|
|
|
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { |
2801
|
|
|
$href = 'https:'; |
2802
|
|
|
} |
2803
|
|
|
|
2804
|
|
|
$href .= '//'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING']; |
2805
|
|
|
|
2806
|
|
|
return $href; |
2807
|
|
|
} |
2808
|
|
|
|
2809
|
|
|
function javascript_escape($str) |
2810
|
|
|
{ |
2811
|
|
|
$new_str = ''; |
2812
|
|
|
|
2813
|
|
|
for ($i = 0; $i < strlen($str); ++$i) { |
2814
|
|
|
if (ord(substr($str, $i, 1)) == 10) { |
2815
|
|
|
$new_str .= '\n'; |
2816
|
|
|
} elseif (ord(substr($str, $i, 1)) == 13) { |
2817
|
|
|
$new_str .= '\r'; |
2818
|
|
|
} else { |
2819
|
|
|
$new_str .= $str{$i}; |
2820
|
|
|
} |
2821
|
|
|
} |
2822
|
|
|
|
2823
|
|
|
$new_str = str_replace("'", "\\'", $new_str); |
2824
|
|
|
|
2825
|
|
|
return $new_str; |
2826
|
|
|
} |
2827
|
|
|
|
2828
|
|
|
function js_escape($str, $keep = true) |
2829
|
|
|
{ |
2830
|
|
|
$str = html_entity_decode(str_replace('\\', '', $str), ENT_QUOTES); |
2831
|
|
|
|
2832
|
|
|
if ($keep) { |
2833
|
|
|
$str = javascript_escape($str); |
2834
|
|
|
} else { |
2835
|
|
|
$str = str_replace("'", ' ', $str); |
2836
|
|
|
$str = str_replace('"', ' ', $str); |
2837
|
|
|
} |
2838
|
|
|
|
2839
|
|
|
return $str; |
2840
|
|
|
|
2841
|
|
|
//end function js_escape |
2842
|
|
|
} |
2843
|
|
|
|
2844
|
|
|
function br2nl($str) |
2845
|
|
|
{ |
2846
|
5 |
|
$regex = '#<[^>]+br.+?>#i'; |
2847
|
5 |
|
preg_match_all($regex, $str, $matches); |
2848
|
|
|
|
2849
|
5 |
|
foreach ($matches[0] as $match) { |
2850
|
|
|
$str = str_replace($match, '<br>', $str); |
2851
|
|
|
} |
2852
|
|
|
|
2853
|
5 |
|
$brs = array('<br>', '<br/>', '<br />'); |
2854
|
5 |
|
$str = str_replace("\r\n", "\n", $str); // make from windows-returns, *nix-returns |
2855
|
5 |
|
$str = str_replace("\n\r", "\n", $str); // make from windows-returns, *nix-returns |
2856
|
5 |
|
$str = str_replace("\r", "\n", $str); // make from windows-returns, *nix-returns |
2857
|
5 |
|
$str = str_ireplace($brs, "\n", $str); // to retrieve it |
2858
|
|
|
|
2859
|
5 |
|
return $str; |
2860
|
|
|
} |
2861
|
|
|
|
2862
|
|
|
/** |
2863
|
|
|
* Private helper function for displaying the contents of a given variable. |
2864
|
|
|
* This function is only intended to be used for SugarCRM internal development. |
2865
|
|
|
* The ppd stands for Pre Print Die. |
2866
|
|
|
*/ |
2867
|
|
|
function _ppd($mixed) |
2868
|
|
|
{ |
2869
|
|
|
} |
2870
|
|
|
|
2871
|
|
|
/** |
2872
|
|
|
* Private helper function for displaying the contents of a given variable in |
2873
|
|
|
* the Logger. This function is only intended to be used for SugarCRM internal |
2874
|
|
|
* development. The pp stands for Pre Print. |
2875
|
|
|
* |
2876
|
|
|
* @param $mixed var to print_r() |
2877
|
|
|
* @param $die boolean end script flow |
2878
|
|
|
* @param $displayStackTrace also show stack trace |
2879
|
|
|
*/ |
2880
|
|
|
function _ppl($mixed, $die = false, $displayStackTrace = false, $loglevel = 'fatal') |
2881
|
|
|
{ |
2882
|
|
|
if (!isset($GLOBALS['log']) || empty($GLOBALS['log'])) { |
2883
|
|
|
$GLOBALS['log'] = LoggerManager:: getLogger('SugarCRM'); |
2884
|
|
|
} |
2885
|
|
|
|
2886
|
|
|
$mix = print_r($mixed, true); // send print_r() output to $mix |
2887
|
|
|
$stack = debug_backtrace(); |
2888
|
|
|
|
2889
|
|
|
$GLOBALS['log']->$loglevel('------------------------------ _ppLogger() output start -----------------------------'); |
2890
|
|
|
$GLOBALS['log']->$loglevel($mix); |
2891
|
|
|
if ($displayStackTrace) { |
2892
|
|
|
foreach ($stack as $position) { |
2893
|
|
|
$GLOBALS['log']->$loglevel($position['file']."({$position['line']})"); |
2894
|
|
|
} |
2895
|
|
|
} |
2896
|
|
|
|
2897
|
|
|
$GLOBALS['log']->$loglevel('------------------------------ _ppLogger() output end -----------------------------'); |
2898
|
|
|
$GLOBALS['log']->$loglevel('------------------------------ _ppLogger() file: '.$stack[0]['file'].' line#: '.$stack[0]['line'].'-----------------------------'); |
2899
|
|
|
|
2900
|
|
|
if ($die) { |
2901
|
|
|
die(); |
2902
|
|
|
} |
2903
|
|
|
} |
2904
|
|
|
|
2905
|
|
|
/** |
2906
|
|
|
* private helper function to quickly show the major, direct, field attributes of a given bean. |
2907
|
|
|
* The ppf stands for Pre[formatted] Print Focus [object]. |
2908
|
|
|
* |
2909
|
|
|
* @param object bean The focus bean |
2910
|
|
|
*/ |
2911
|
|
|
function _ppf($bean, $die = false) |
2912
|
|
|
{ |
2913
|
|
|
} |
2914
|
|
|
|
2915
|
|
|
/** |
2916
|
|
|
* Private helper function for displaying the contents of a given variable. |
2917
|
|
|
* This function is only intended to be used for SugarCRM internal development. |
2918
|
|
|
* The pp stands for Pre Print. |
2919
|
|
|
*/ |
2920
|
|
|
function _pp($mixed) |
2921
|
|
|
{ |
2922
|
|
|
} |
2923
|
|
|
|
2924
|
|
|
/** |
2925
|
|
|
* Private helper function for displaying the contents of a given variable. |
2926
|
|
|
* This function is only intended to be used for SugarCRM internal development. |
2927
|
|
|
* The pp stands for Pre Print. |
2928
|
|
|
*/ |
2929
|
|
|
function _pstack_trace($mixed = null) |
2930
|
|
|
{ |
2931
|
|
|
} |
2932
|
|
|
|
2933
|
|
|
/** |
2934
|
|
|
* Private helper function for displaying the contents of a given variable. |
2935
|
|
|
* This function is only intended to be used for SugarCRM internal development. |
2936
|
|
|
* The pp stands for Pre Print Trace. |
2937
|
|
|
*/ |
2938
|
|
|
function _ppt($mixed, $textOnly = false) |
2939
|
|
|
{ |
2940
|
|
|
} |
2941
|
|
|
|
2942
|
|
|
/** |
2943
|
|
|
* Private helper function for displaying the contents of a given variable. |
2944
|
|
|
* This function is only intended to be used for SugarCRM internal development. |
2945
|
|
|
* The pp stands for Pre Print Trace Die. |
2946
|
|
|
*/ |
2947
|
|
|
function _pptd($mixed) |
2948
|
|
|
{ |
2949
|
|
|
} |
2950
|
|
|
|
2951
|
|
|
/** |
2952
|
|
|
* Private helper function for decoding javascript UTF8 |
2953
|
|
|
* This function is only intended to be used for SugarCRM internal development. |
2954
|
|
|
*/ |
2955
|
|
|
function decodeJavascriptUTF8($str) |
2956
|
|
|
{ |
2957
|
|
|
} |
2958
|
|
|
|
2959
|
|
|
/** |
2960
|
|
|
* Will check if a given PHP version string is supported (tested on this ver), |
2961
|
|
|
* unsupported (results unknown), or invalid (something will break on this |
2962
|
|
|
* ver). Do not pass in any pararameter to default to a check against the |
2963
|
|
|
* current environment's PHP version. |
2964
|
|
|
* |
2965
|
|
|
* @return 1 implies supported, 0 implies unsupported, -1 implies invalid |
2966
|
|
|
*/ |
2967
|
|
|
function check_php_version($sys_php_version = '') |
2968
|
|
|
{ |
2969
|
|
|
$sys_php_version = empty($sys_php_version) ? constant('PHP_VERSION') : $sys_php_version; |
2970
|
|
|
// versions below $min_considered_php_version considered invalid by default, |
2971
|
|
|
// versions equal to or above this ver will be considered depending |
2972
|
|
|
// on the rules that follow |
2973
|
|
|
$min_considered_php_version = '5.3.0'; |
2974
|
|
|
|
2975
|
|
|
// only the supported versions, |
2976
|
|
|
// should be mutually exclusive with $invalid_php_versions |
2977
|
|
|
$supported_php_versions = array( |
2978
|
|
|
'5.3.0', |
2979
|
|
|
); |
2980
|
|
|
|
2981
|
|
|
// invalid versions above the $min_considered_php_version, |
2982
|
|
|
// should be mutually exclusive with $supported_php_versions |
2983
|
|
|
|
2984
|
|
|
// SugarCRM prohibits install on PHP 5.2.7 on all platforms |
2985
|
|
|
$invalid_php_versions = array('5.2.7'); |
2986
|
|
|
|
2987
|
|
|
// default unsupported |
2988
|
|
|
$retval = 0; |
2989
|
|
|
|
2990
|
|
|
// versions below $min_considered_php_version are invalid |
2991
|
|
|
if (1 == version_compare($sys_php_version, $min_considered_php_version, '<')) { |
2992
|
|
|
$retval = -1; |
2993
|
|
|
} |
2994
|
|
|
|
2995
|
|
|
// supported version check overrides default unsupported |
2996
|
|
|
foreach ($supported_php_versions as $ver) { |
2997
|
|
|
if (1 == version_compare($sys_php_version, $ver, 'eq') || strpos($sys_php_version, $ver) !== false) { |
2998
|
|
|
$retval = 1; |
2999
|
|
|
break; |
3000
|
|
|
} |
3001
|
|
|
} |
3002
|
|
|
|
3003
|
|
|
// invalid version check overrides default unsupported |
3004
|
|
|
foreach ($invalid_php_versions as $ver) { |
3005
|
|
|
if (1 == version_compare($sys_php_version, $ver, 'eq') && strpos($sys_php_version, $ver) !== false) { |
3006
|
|
|
$retval = -1; |
3007
|
|
|
break; |
3008
|
|
|
} |
3009
|
|
|
} |
3010
|
|
|
|
3011
|
|
|
//allow a redhat distro to install, regardless of version. We are assuming the redhat naming convention is followed |
3012
|
|
|
//and the php version contains 'rh' characters |
3013
|
|
|
if (strpos($sys_php_version, 'rh') !== false) { |
3014
|
|
|
$retval = 1; |
3015
|
|
|
} |
3016
|
|
|
|
3017
|
|
|
return $retval; |
3018
|
|
|
} |
3019
|
|
|
|
3020
|
|
|
/** |
3021
|
|
|
* Will check if a given IIS version string is supported (tested on this ver), |
3022
|
|
|
* unsupported (results unknown), or invalid (something will break on this |
3023
|
|
|
* ver). |
3024
|
|
|
* |
3025
|
|
|
* @return 1 implies supported, 0 implies unsupported, -1 implies invalid |
3026
|
|
|
*/ |
3027
|
|
|
function check_iis_version($sys_iis_version = '') |
3028
|
|
|
{ |
3029
|
|
|
$server_software = $_SERVER['SERVER_SOFTWARE']; |
3030
|
|
|
$iis_version = ''; |
3031
|
|
|
if (strpos($server_software, 'Microsoft-IIS') !== false && preg_match_all("/^.*\/(\d+\.?\d*)$/", $server_software, $out)) { |
3032
|
|
|
$iis_version = $out[1][0]; |
3033
|
|
|
} |
3034
|
|
|
|
3035
|
|
|
$sys_iis_version = empty($sys_iis_version) ? $iis_version : $sys_iis_version; |
3036
|
|
|
|
3037
|
|
|
// versions below $min_considered_iis_version considered invalid by default, |
3038
|
|
|
// versions equal to or above this ver will be considered depending |
3039
|
|
|
// on the rules that follow |
3040
|
|
|
$min_considered_iis_version = '6.0'; |
3041
|
|
|
|
3042
|
|
|
// only the supported versions, |
3043
|
|
|
// should be mutually exclusive with $invalid_iis_versions |
3044
|
|
|
$supported_iis_versions = array('6.0', '7.0'); |
3045
|
|
|
$unsupported_iis_versions = array(); |
3046
|
|
|
$invalid_iis_versions = array('5.0'); |
3047
|
|
|
|
3048
|
|
|
// default unsupported |
3049
|
|
|
$retval = 0; |
3050
|
|
|
|
3051
|
|
|
// versions below $min_considered_iis_version are invalid |
3052
|
|
|
if (1 == version_compare($sys_iis_version, $min_considered_iis_version, '<')) { |
3053
|
|
|
$retval = -1; |
3054
|
|
|
} |
3055
|
|
|
|
3056
|
|
|
// supported version check overrides default unsupported |
3057
|
|
|
foreach ($supported_iis_versions as $ver) { |
3058
|
|
|
if (1 == version_compare($sys_iis_version, $ver, 'eq') || strpos($sys_iis_version, $ver) !== false) { |
3059
|
|
|
$retval = 1; |
3060
|
|
|
break; |
3061
|
|
|
} |
3062
|
|
|
} |
3063
|
|
|
|
3064
|
|
|
// unsupported version check overrides default unsupported |
3065
|
|
|
foreach ($unsupported_iis_versions as $ver) { |
3066
|
|
|
if (1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version, $ver) !== false) { |
3067
|
|
|
$retval = 0; |
3068
|
|
|
break; |
3069
|
|
|
} |
3070
|
|
|
} |
3071
|
|
|
|
3072
|
|
|
// invalid version check overrides default unsupported |
3073
|
|
|
foreach ($invalid_iis_versions as $ver) { |
3074
|
|
|
if (1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version, $ver) !== false) { |
3075
|
|
|
$retval = -1; |
3076
|
|
|
break; |
3077
|
|
|
} |
3078
|
|
|
} |
3079
|
|
|
|
3080
|
|
|
return $retval; |
3081
|
|
|
} |
3082
|
|
|
|
3083
|
|
|
function pre_login_check() |
3084
|
|
|
{ |
3085
|
|
|
global $action, $login_error; |
3086
|
|
|
if (!empty($action) && $action == 'Login') { |
3087
|
|
|
if (!empty($login_error)) { |
3088
|
|
|
$login_error = htmlentities($login_error); |
3089
|
|
|
$login_error = str_replace(array('<pre>', '</pre>', "\r\n", "\n"), '<br>', $login_error); |
3090
|
|
|
$_SESSION['login_error'] = $login_error; |
3091
|
|
|
echo '<script> |
3092
|
|
|
function set_focus() {} |
3093
|
|
|
if(document.getElementById("post_error")) { |
3094
|
|
|
document.getElementById("post_error").innerHTML="'.$login_error.'"; |
3095
|
|
|
document.getElementById("cant_login").value=1; |
3096
|
|
|
document.getElementById("login_button").disabled = true; |
3097
|
|
|
document.getElementById("user_name").disabled = true; |
3098
|
|
|
//document.getElementById("user_password").disabled = true; |
3099
|
|
|
} |
3100
|
|
|
</script>'; |
3101
|
|
|
} |
3102
|
|
|
} |
3103
|
|
|
} |
3104
|
|
|
|
3105
|
|
|
function sugar_cleanup($exit = false) |
3106
|
|
|
{ |
3107
|
|
|
static $called = false; |
3108
|
|
|
if ($called) { |
3109
|
|
|
return; |
3110
|
|
|
} |
3111
|
|
|
$called = true; |
3112
|
|
|
set_include_path(realpath(dirname(__FILE__).'/..').PATH_SEPARATOR.get_include_path()); |
3113
|
|
|
chdir(realpath(dirname(__FILE__).'/..')); |
3114
|
|
|
global $sugar_config; |
3115
|
|
|
require_once 'include/utils/LogicHook.php'; |
3116
|
|
|
LogicHook::initialize(); |
3117
|
|
|
$GLOBALS['logic_hook']->call_custom_logic('', 'server_round_trip'); |
3118
|
|
|
|
3119
|
|
|
//added this check to avoid errors during install. |
3120
|
|
|
if (empty($sugar_config['dbconfig'])) { |
3121
|
|
|
if ($exit) { |
3122
|
|
|
exit; |
3123
|
|
|
} else { |
3124
|
|
|
return; |
3125
|
|
|
} |
3126
|
|
|
} |
3127
|
|
|
|
3128
|
|
|
if (!class_exists('Tracker', true)) { |
3129
|
|
|
require_once 'modules/Trackers/Tracker.php'; |
3130
|
|
|
} |
3131
|
|
|
Tracker::logPage(); |
3132
|
|
|
// Now write the cached tracker_queries |
3133
|
|
|
if (!empty($GLOBALS['savePreferencesToDB']) && $GLOBALS['savePreferencesToDB']) { |
3134
|
|
|
if (isset($GLOBALS['current_user']) && $GLOBALS['current_user'] instanceof User) { |
3135
|
|
|
$GLOBALS['current_user']->savePreferencesToDB(); |
3136
|
|
|
} |
3137
|
|
|
} |
3138
|
|
|
|
3139
|
|
|
//check to see if this is not an `ajax call AND the user preference error flag is set |
3140
|
|
|
if ( |
3141
|
|
|
(isset($_SESSION['USER_PREFRENCE_ERRORS']) && $_SESSION['USER_PREFRENCE_ERRORS']) |
3142
|
|
|
&& ($_REQUEST['action'] != 'modulelistmenu' && $_REQUEST['action'] != 'DynamicAction') |
3143
|
|
|
&& ($_REQUEST['action'] != 'favorites' && $_REQUEST['action'] != 'DynamicAction') |
3144
|
|
|
&& (empty($_REQUEST['to_pdf']) || !$_REQUEST['to_pdf']) |
3145
|
|
|
&& (empty($_REQUEST['sugar_body_only']) || !$_REQUEST['sugar_body_only']) |
3146
|
|
|
|
3147
|
|
|
) { |
3148
|
|
|
global $app_strings; |
3149
|
|
|
//this is not an ajax call and the user preference error flag is set, so reset the flag and print js to flash message |
3150
|
|
|
$err_mess = $app_strings['ERROR_USER_PREFS']; |
3151
|
|
|
$_SESSION['USER_PREFRENCE_ERRORS'] = false; |
3152
|
|
|
echo " |
3153
|
|
|
<script> |
3154
|
|
|
ajaxStatus.flashStatus('$err_mess',7000); |
3155
|
|
|
</script>"; |
3156
|
|
|
} |
3157
|
|
|
|
3158
|
|
|
pre_login_check(); |
3159
|
|
|
if (class_exists('DBManagerFactory')) { |
3160
|
|
|
$db = DBManagerFactory::getInstance(); |
3161
|
|
|
$db->disconnect(); |
3162
|
|
|
if ($exit) { |
3163
|
|
|
exit; |
3164
|
|
|
} |
3165
|
|
|
} |
3166
|
|
|
} |
3167
|
|
|
|
3168
|
|
|
register_shutdown_function('sugar_cleanup'); |
3169
|
|
|
|
3170
|
|
|
/* |
3171
|
|
|
check_logic_hook - checks to see if your custom logic is in the logic file |
3172
|
|
|
if not, it will add it. If the file isn't built yet, it will create the file |
3173
|
|
|
|
3174
|
|
|
*/ |
3175
|
|
|
function check_logic_hook_file($module_name, $event, $action_array) |
3176
|
|
|
{ |
3177
|
|
|
require_once 'include/utils/logic_utils.php'; |
3178
|
|
|
$add_logic = false; |
3179
|
|
|
|
3180
|
|
|
if (file_exists("custom/modules/$module_name/logic_hooks.php")) { |
3181
|
|
|
$hook_array = get_hook_array($module_name); |
3182
|
|
|
|
3183
|
|
|
if (check_existing_element($hook_array, $event, $action_array) == true) { |
3184
|
|
|
//the hook at hand is present, so do nothing |
3185
|
|
|
} else { |
3186
|
|
|
$add_logic = true; |
3187
|
|
|
|
3188
|
|
|
$logic_count = 0; |
3189
|
|
|
if (!empty($hook_array[$event])) { |
3190
|
|
|
$logic_count = count($hook_array[$event]); |
3191
|
|
|
} |
3192
|
|
|
|
3193
|
|
|
if ($action_array[0] == '') { |
3194
|
|
|
$action_array[0] = $logic_count + 1; |
3195
|
|
|
} |
3196
|
|
|
$hook_array[$event][] = $action_array; |
3197
|
|
|
} |
3198
|
|
|
//end if the file exists already |
3199
|
|
|
} else { |
3200
|
|
|
$add_logic = true; |
3201
|
|
|
if ($action_array[0] == '') { |
3202
|
|
|
$action_array[0] = 1; |
3203
|
|
|
} |
3204
|
|
|
$hook_array = array(); |
3205
|
|
|
$hook_array[$event][] = $action_array; |
3206
|
|
|
//end if else file exists already |
3207
|
|
|
} |
3208
|
|
|
if ($add_logic == true) { |
3209
|
|
|
|
3210
|
|
|
//reorder array by element[0] |
3211
|
|
|
//$hook_array = reorder_array($hook_array, $event); |
3212
|
|
|
//!!!Finish this above TODO |
3213
|
|
|
|
3214
|
|
|
$new_contents = replace_or_add_logic_type($hook_array); |
3215
|
|
|
write_logic_file($module_name, $new_contents); |
3216
|
|
|
|
3217
|
|
|
//end if add_element is true |
3218
|
|
|
} |
3219
|
|
|
|
3220
|
|
|
//end function check_logic_hook_file |
3221
|
|
|
} |
3222
|
|
|
|
3223
|
|
|
function remove_logic_hook($module_name, $event, $action_array) |
3224
|
|
|
{ |
3225
|
|
|
require_once 'include/utils/logic_utils.php'; |
3226
|
|
|
$add_logic = false; |
3227
|
|
|
|
3228
|
|
|
if (file_exists('custom/modules/'.$module_name.'/logic_hooks.php')) { |
3229
|
|
|
// The file exists, let's make sure the hook is there |
3230
|
|
|
$hook_array = get_hook_array($module_name); |
3231
|
|
|
|
3232
|
|
|
if (check_existing_element($hook_array, $event, $action_array) == true) { |
3233
|
|
|
// The hook is there, time to take it out. |
3234
|
|
|
|
3235
|
|
|
foreach ($hook_array[$event] as $i => $hook) { |
3236
|
|
|
// We don't do a full comparison below just in case the filename changes |
3237
|
|
|
if ($hook[0] == $action_array[0] |
3238
|
|
|
&& $hook[1] == $action_array[1] |
3239
|
|
|
&& $hook[3] == $action_array[3] |
3240
|
|
|
&& $hook[4] == $action_array[4] |
3241
|
|
|
) { |
3242
|
|
|
unset($hook_array[$event][$i]); |
3243
|
|
|
} |
3244
|
|
|
} |
3245
|
|
|
|
3246
|
|
|
$new_contents = replace_or_add_logic_type($hook_array); |
3247
|
|
|
write_logic_file($module_name, $new_contents); |
3248
|
|
|
} |
3249
|
|
|
} |
3250
|
|
|
} |
3251
|
|
|
|
3252
|
|
|
function display_stack_trace($textOnly = false) |
3253
|
|
|
{ |
3254
|
|
|
$stack = debug_backtrace(); |
3255
|
|
|
|
3256
|
|
|
echo "\n\n display_stack_trace caller, file: ".$stack[0]['file'].' line#: '.$stack[0]['line']; |
3257
|
|
|
|
3258
|
|
|
if (!$textOnly) { |
3259
|
|
|
echo '<br>'; |
3260
|
|
|
} |
3261
|
|
|
|
3262
|
|
|
$first = true; |
3263
|
|
|
$out = ''; |
3264
|
|
|
|
3265
|
|
|
foreach ($stack as $item) { |
3266
|
|
|
$file = ''; |
3267
|
|
|
$class = ''; |
3268
|
|
|
$line = ''; |
3269
|
|
|
$function = ''; |
3270
|
|
|
|
3271
|
|
|
if (isset($item['file'])) { |
3272
|
|
|
$file = $item['file']; |
3273
|
|
|
} |
3274
|
|
|
if (isset($item['class'])) { |
3275
|
|
|
$class = $item['class']; |
3276
|
|
|
} |
3277
|
|
|
if (isset($item['line'])) { |
3278
|
|
|
$line = $item['line']; |
3279
|
|
|
} |
3280
|
|
|
if (isset($item['function'])) { |
3281
|
|
|
$function = $item['function']; |
3282
|
|
|
} |
3283
|
|
|
|
3284
|
|
|
if (!$first) { |
3285
|
|
|
if (!$textOnly) { |
3286
|
|
|
$out .= '<font color="black"><b>'; |
3287
|
|
|
} |
3288
|
|
|
|
3289
|
|
|
$out .= $file; |
3290
|
|
|
|
3291
|
|
|
if (!$textOnly) { |
3292
|
|
|
$out .= '</b></font><font color="blue">'; |
3293
|
|
|
} |
3294
|
|
|
|
3295
|
|
|
$out .= "[L:{$line}]"; |
3296
|
|
|
|
3297
|
|
|
if (!$textOnly) { |
3298
|
|
|
$out .= '</font><font color="red">'; |
3299
|
|
|
} |
3300
|
|
|
|
3301
|
|
|
$out .= "({$class}:{$function})"; |
3302
|
|
|
|
3303
|
|
|
if (!$textOnly) { |
3304
|
|
|
$out .= '</font><br>'; |
3305
|
|
|
} else { |
3306
|
|
|
$out .= "\n"; |
3307
|
|
|
} |
3308
|
|
|
} else { |
3309
|
|
|
$first = false; |
3310
|
|
|
} |
3311
|
|
|
} |
3312
|
|
|
|
3313
|
|
|
echo $out; |
3314
|
|
|
} |
3315
|
|
|
|
3316
|
|
|
function StackTraceErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) |
3317
|
|
|
{ |
3318
|
|
|
$error_msg = " $errstr occurred in <b>$errfile</b> on line $errline [".date('Y-m-d H:i:s').']'; |
3319
|
|
|
$halt_script = true; |
3320
|
|
|
switch ($errno) { |
3321
|
|
|
case 2048 : |
3322
|
|
|
return; //depricated we have lots of these ignore them |
3323
|
|
|
case E_USER_NOTICE: |
3324
|
|
|
case E_NOTICE: |
3325
|
|
|
if (error_reporting() & E_NOTICE) { |
3326
|
|
|
$halt_script = false; |
3327
|
|
|
$type = 'Notice'; |
3328
|
|
|
} else { |
3329
|
|
|
return; |
3330
|
|
|
} |
3331
|
|
|
break; |
3332
|
|
|
case E_USER_WARNING: |
3333
|
|
|
case E_COMPILE_WARNING: |
3334
|
|
|
case E_CORE_WARNING: |
3335
|
|
|
case E_WARNING: |
3336
|
|
|
|
3337
|
|
|
$halt_script = false; |
3338
|
|
|
$type = 'Warning'; |
3339
|
|
|
break; |
3340
|
|
|
|
3341
|
|
|
case E_USER_ERROR: |
3342
|
|
|
case E_COMPILE_ERROR: |
3343
|
|
|
case E_CORE_ERROR: |
3344
|
|
|
case E_ERROR: |
3345
|
|
|
|
3346
|
|
|
$type = 'Fatal Error'; |
3347
|
|
|
break; |
3348
|
|
|
|
3349
|
|
|
case E_PARSE: |
3350
|
|
|
|
3351
|
|
|
$type = 'Parse Error'; |
3352
|
|
|
break; |
3353
|
|
|
|
3354
|
|
|
default: |
3355
|
|
|
//don't know what it is might not be so bad |
3356
|
|
|
$halt_script = false; |
3357
|
|
|
$type = "Unknown Error ($errno)"; |
3358
|
|
|
break; |
3359
|
|
|
} |
3360
|
|
|
$error_msg = '<b>'.$type.'</b>:'.$error_msg; |
3361
|
|
|
echo $error_msg; |
3362
|
|
|
display_stack_trace(); |
3363
|
|
|
if ($halt_script) { |
3364
|
|
|
exit -1; |
3365
|
|
|
} |
3366
|
|
|
} |
3367
|
|
|
|
3368
|
|
|
if (isset($sugar_config['stack_trace_errors']) && $sugar_config['stack_trace_errors']) { |
3369
|
|
|
set_error_handler('StackTraceErrorHandler'); |
3370
|
|
|
} |
3371
|
|
|
function get_sub_cookies($name) |
3372
|
|
|
{ |
3373
|
|
|
$cookies = array(); |
3374
|
|
|
if (isset($_COOKIE[$name])) { |
3375
|
|
|
$subs = explode('#', $_COOKIE[$name]); |
3376
|
|
|
foreach ($subs as $cookie) { |
3377
|
|
|
if (!empty($cookie)) { |
3378
|
|
|
$cookie = explode('=', $cookie); |
3379
|
|
|
|
3380
|
|
|
$cookies[$cookie[0]] = $cookie[1]; |
3381
|
|
|
} |
3382
|
|
|
} |
3383
|
|
|
} |
3384
|
|
|
|
3385
|
|
|
return $cookies; |
3386
|
|
|
} |
3387
|
|
|
|
3388
|
|
|
function mark_delete_components($sub_object_array, $run_second_level = false, $sub_sub_array = '') |
3389
|
|
|
{ |
3390
|
|
|
if (!empty($sub_object_array)) { |
3391
|
|
|
foreach ($sub_object_array as $sub_object) { |
3392
|
|
|
|
3393
|
|
|
//run_second level is set to true if you need to remove sub-sub components |
3394
|
|
|
if ($run_second_level == true) { |
3395
|
|
|
mark_delete_components($sub_object->get_linked_beans($sub_sub_array['rel_field'], $sub_sub_array['rel_module'])); |
3396
|
|
|
|
3397
|
|
|
//end if run_second_level is true |
3398
|
|
|
} |
3399
|
|
|
$sub_object->mark_deleted($sub_object->id); |
3400
|
|
|
//end foreach sub component |
3401
|
|
|
} |
3402
|
|
|
//end if this is not empty |
3403
|
|
|
} |
3404
|
|
|
|
3405
|
|
|
//end function mark_delete_components |
3406
|
|
|
} |
3407
|
|
|
|
3408
|
|
|
/** |
3409
|
|
|
* For translating the php.ini memory values into bytes. e.g. input value of '8M' will return 8388608. |
3410
|
|
|
*/ |
3411
|
|
|
function return_bytes($val) |
3412
|
|
|
{ |
3413
|
|
|
$val = trim($val); |
3414
|
|
|
$last = strtolower($val{strlen($val) - 1}); |
3415
|
|
|
|
3416
|
|
|
switch ($last) { |
3417
|
|
|
// The 'G' modifier is available since PHP 5.1.0 |
3418
|
|
|
case 'g': |
3419
|
|
|
$val *= 1024; |
3420
|
|
|
case 'm': |
3421
|
|
|
$val *= 1024; |
3422
|
|
|
case 'k': |
3423
|
|
|
$val *= 1024; |
3424
|
|
|
} |
3425
|
|
|
|
3426
|
|
|
return $val; |
3427
|
|
|
} |
3428
|
|
|
|
3429
|
|
|
/** |
3430
|
|
|
* Adds the href HTML tags around any URL in the $string. |
3431
|
|
|
*/ |
3432
|
|
|
function url2html($string) |
3433
|
|
|
{ |
3434
|
|
|
// |
3435
|
2 |
|
$return_string = preg_replace('/(\w+:\/\/)(\S+)/', ' <a href="\\1\\2" target="_new" style="font-weight: normal;">\\1\\2</a>', $string); |
3436
|
|
|
|
3437
|
2 |
|
return $return_string; |
3438
|
|
|
} |
3439
|
|
|
|
3440
|
|
|
// End customization by Julian |
3441
|
|
|
|
3442
|
|
|
/** |
3443
|
|
|
* tries to determine whether the Host machine is a Windows machine. |
3444
|
|
|
*/ |
3445
|
|
|
function is_windows() |
3446
|
|
|
{ |
3447
|
876 |
|
static $is_windows = null; |
3448
|
876 |
|
if (!isset($is_windows)) { |
3449
|
1 |
|
$is_windows = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'; |
3450
|
|
|
} |
3451
|
|
|
|
3452
|
876 |
|
return $is_windows; |
3453
|
|
|
} |
3454
|
|
|
|
3455
|
|
|
/** |
3456
|
|
|
* equivalent for windows filesystem for PHP's is_writable(). |
3457
|
|
|
* |
3458
|
|
|
* @param string file Full path to the file/dir |
3459
|
|
|
* |
3460
|
|
|
* @return bool true if writable |
3461
|
|
|
*/ |
3462
|
|
|
function is_writable_windows($file) |
3463
|
|
|
{ |
3464
|
|
|
if ($file{strlen($file) - 1} == '/') { |
3465
|
|
|
return is_writable_windows($file.uniqid(mt_rand()).'.tmp'); |
3466
|
|
|
} |
3467
|
|
|
|
3468
|
|
|
// the assumption here is that Windows has an inherited permissions scheme |
3469
|
|
|
// any file that is a descendant of an unwritable directory will inherit |
3470
|
|
|
// that property and will trigger a failure below. |
3471
|
|
|
if (is_dir($file)) { |
3472
|
|
|
return true; |
3473
|
|
|
} |
3474
|
|
|
|
3475
|
|
|
$file = str_replace('/', '\\', $file); |
3476
|
|
|
|
3477
|
|
|
if (file_exists($file)) { |
3478
|
|
|
if (!($f = @sugar_fopen($file, 'r+'))) { |
3479
|
|
|
return false; |
3480
|
|
|
} |
3481
|
|
|
fclose($f); |
3482
|
|
|
|
3483
|
|
|
return true; |
3484
|
|
|
} |
3485
|
|
|
|
3486
|
|
|
if (!($f = @sugar_fopen($file, 'w'))) { |
3487
|
|
|
return false; |
3488
|
|
|
} |
3489
|
|
|
fclose($f); |
3490
|
|
|
unlink($file); |
3491
|
|
|
|
3492
|
|
|
return true; |
3493
|
|
|
} |
3494
|
|
|
|
3495
|
|
|
/** |
3496
|
|
|
* best guesses Timezone based on webserver's TZ settings. |
3497
|
|
|
*/ |
3498
|
|
|
function lookupTimezone($userOffset = 0) |
3499
|
|
|
{ |
3500
|
|
|
return TimeDate::guessTimezone($userOffset); |
3501
|
|
|
} |
3502
|
|
|
|
3503
|
|
|
function convert_module_to_singular($module_array) |
3504
|
|
|
{ |
3505
|
|
|
global $beanList; |
3506
|
|
|
|
3507
|
|
|
foreach ($module_array as $key => $value) { |
3508
|
|
|
if (!empty($beanList[$value])) { |
3509
|
|
|
$module_array[$key] = $beanList[$value]; |
3510
|
|
|
} |
3511
|
|
|
|
3512
|
|
|
if ($value == 'Cases') { |
3513
|
|
|
$module_array[$key] = 'Case'; |
3514
|
|
|
} |
3515
|
|
|
if ($key == 'projecttask') { |
3516
|
|
|
$module_array['ProjectTask'] = 'Project Task'; |
3517
|
|
|
unset($module_array[$key]); |
3518
|
|
|
} |
3519
|
|
|
} |
3520
|
|
|
|
3521
|
|
|
return $module_array; |
3522
|
|
|
|
3523
|
|
|
//end function convert_module_to_singular |
3524
|
|
|
} |
3525
|
|
|
|
3526
|
|
|
/* |
3527
|
|
|
* Given the bean_name which may be plural or singular return the singular |
3528
|
|
|
* bean_name. This is important when you need to include files. |
3529
|
|
|
*/ |
3530
|
|
|
function get_singular_bean_name($bean_name) |
3531
|
|
|
{ |
3532
|
|
|
global $beanFiles, $beanList; |
3533
|
|
|
if (array_key_exists($bean_name, $beanList)) { |
3534
|
|
|
return $beanList[$bean_name]; |
3535
|
|
|
} else { |
3536
|
|
|
return $bean_name; |
3537
|
|
|
} |
3538
|
|
|
} |
3539
|
|
|
|
3540
|
|
|
/* |
3541
|
|
|
* Given the potential module name (singular name, renamed module name) |
3542
|
|
|
* Return the real internal module name. |
3543
|
|
|
*/ |
3544
|
|
|
function get_module_from_singular($singular) |
3545
|
|
|
{ |
3546
|
|
|
|
3547
|
|
|
// find the internal module name for a singular name |
3548
|
|
|
if (isset($GLOBALS['app_list_strings']['moduleListSingular'])) { |
3549
|
|
|
$singular_modules = $GLOBALS['app_list_strings']['moduleListSingular']; |
3550
|
|
|
|
3551
|
|
|
foreach ($singular_modules as $mod_name => $sin_name) { |
3552
|
|
|
if ($singular == $sin_name and $mod_name != $sin_name) { |
3553
|
|
|
return $mod_name; |
3554
|
|
|
} |
3555
|
|
|
} |
3556
|
|
|
} |
3557
|
|
|
|
3558
|
|
|
// find the internal module name for a renamed module |
3559
|
|
|
if (isset($GLOBALS['app_list_strings']['moduleList'])) { |
3560
|
|
|
$moduleList = $GLOBALS['app_list_strings']['moduleList']; |
3561
|
|
|
|
3562
|
|
|
foreach ($moduleList as $mod_name => $name) { |
3563
|
|
|
if ($singular == $name and $mod_name != $name) { |
3564
|
|
|
return $mod_name; |
3565
|
|
|
} |
3566
|
|
|
} |
3567
|
|
|
} |
3568
|
|
|
|
3569
|
|
|
// if it's not a singular name, nor a renamed name, return the original value |
3570
|
|
|
return $singular; |
3571
|
|
|
} |
3572
|
|
|
|
3573
|
|
|
function get_label($label_tag, $temp_module_strings) |
3574
|
|
|
{ |
3575
|
|
|
global $app_strings; |
3576
|
|
|
if (!empty($temp_module_strings[$label_tag])) { |
3577
|
|
|
$label_name = $temp_module_strings[$label_tag]; |
3578
|
|
|
} else { |
3579
|
|
|
if (!empty($app_strings[$label_tag])) { |
3580
|
|
|
$label_name = $app_strings[$label_tag]; |
3581
|
|
|
} else { |
3582
|
|
|
$label_name = $label_tag; |
3583
|
|
|
} |
3584
|
|
|
} |
3585
|
|
|
|
3586
|
|
|
return $label_name; |
3587
|
|
|
|
3588
|
|
|
//end function get_label |
3589
|
|
|
} |
3590
|
|
|
|
3591
|
|
|
function search_filter_rel_info(&$focus, $tar_rel_module, $relationship_name) |
3592
|
|
|
{ |
3593
|
|
|
$rel_list = array(); |
3594
|
|
|
|
3595
|
|
|
foreach ($focus->relationship_fields as $rel_key => $rel_value) { |
3596
|
|
|
if ($rel_value == $relationship_name) { |
3597
|
|
|
$temp_bean = BeanFactory::getBean($tar_rel_module, $focus->$rel_key); |
3598
|
|
|
if ($temp_bean) { |
3599
|
|
|
$rel_list[] = $temp_bean; |
3600
|
|
|
|
3601
|
|
|
return $rel_list; |
3602
|
|
|
} |
3603
|
|
|
} |
3604
|
|
|
} |
3605
|
|
|
|
3606
|
|
|
foreach ($focus->field_defs as $field_name => $field_def) { |
3607
|
|
|
//Check if the relationship_name matches a "relate" field |
3608
|
|
|
if (!empty($field_def['type']) && $field_def['type'] == 'relate' |
3609
|
|
|
&& !empty($field_def['id_name']) && !empty($focus->field_defs[$field_def['id_name']]) |
3610
|
|
|
&& !empty($focus->field_defs[$field_def['id_name']]['relationship']) |
3611
|
|
|
&& $focus->field_defs[$field_def['id_name']]['relationship'] == $relationship_name |
3612
|
|
|
) { |
3613
|
|
|
$temp_bean = BeanFactory::getBean($tar_rel_module, $field_def['id_name']); |
3614
|
|
|
if ($temp_bean) { |
3615
|
|
|
$rel_list[] = $temp_bean; |
3616
|
|
|
|
3617
|
|
|
return $rel_list; |
3618
|
|
|
} |
3619
|
|
|
//Check if the relationship_name matches a "link" in a relate field |
3620
|
|
|
} elseif (!empty($rel_value['link']) && !empty($rel_value['id_name']) && $rel_value['link'] == $relationship_name) { |
3621
|
|
|
$temp_bean = BeanFactory::getBean($tar_rel_module, $rel_value['id_name']); |
3622
|
|
|
if ($temp_bean) { |
3623
|
|
|
$rel_list[] = $temp_bean; |
3624
|
|
|
|
3625
|
|
|
return $rel_list; |
3626
|
|
|
} |
3627
|
|
|
} |
3628
|
|
|
} |
3629
|
|
|
|
3630
|
|
|
// special case for unlisted parent-type relationships |
3631
|
|
|
if (!empty($focus->parent_type) && $focus->parent_type == $tar_rel_module && !empty($focus->parent_id)) { |
3632
|
|
|
$temp_bean = BeanFactory::getBean($tar_rel_module, $focus->parent_id); |
3633
|
|
|
if ($temp_bean) { |
3634
|
|
|
$rel_list[] = $temp_bean; |
3635
|
|
|
|
3636
|
|
|
return $rel_list; |
3637
|
|
|
} |
3638
|
|
|
} |
3639
|
|
|
|
3640
|
|
|
return $rel_list; |
3641
|
|
|
|
3642
|
|
|
//end function search_filter_rel_info |
3643
|
|
|
} |
3644
|
|
|
|
3645
|
|
|
function get_module_info($module_name) |
3646
|
|
|
{ |
3647
|
6 |
|
global $beanList; |
3648
|
6 |
|
global $dictionary; |
3649
|
|
|
|
3650
|
|
|
//Get dictionary and focus data for module |
3651
|
6 |
|
$vardef_name = $beanList[$module_name]; |
3652
|
|
|
|
3653
|
6 |
|
if ($vardef_name == 'aCase') { |
3654
|
|
|
$class_name = 'Case'; |
3655
|
|
|
} else { |
3656
|
6 |
|
$class_name = $vardef_name; |
3657
|
|
|
} |
3658
|
|
|
|
3659
|
6 |
|
if (!file_exists('modules/'.$module_name.'/'.$class_name.'.php')) { |
3660
|
|
|
return; |
3661
|
|
|
} |
3662
|
|
|
|
3663
|
6 |
|
include_once 'modules/'.$module_name.'/'.$class_name.'.php'; |
3664
|
|
|
|
3665
|
6 |
|
$module_bean = new $vardef_name(); |
3666
|
|
|
|
3667
|
6 |
|
return $module_bean; |
3668
|
|
|
//end function get_module_table |
3669
|
|
|
} |
3670
|
|
|
|
3671
|
|
|
/** |
3672
|
|
|
* In order to have one place to obtain the proper object name. aCase for example causes issues throughout the application. |
3673
|
|
|
* |
3674
|
|
|
* @param string $moduleName |
3675
|
|
|
*/ |
3676
|
|
|
function get_valid_bean_name($module_name) |
3677
|
|
|
{ |
3678
|
|
|
global $beanList; |
3679
|
|
|
|
3680
|
|
|
$vardef_name = $beanList[$module_name]; |
3681
|
|
|
if ($vardef_name == 'aCase') { |
3682
|
|
|
$bean_name = 'Case'; |
3683
|
|
|
} else { |
3684
|
|
|
$bean_name = $vardef_name; |
3685
|
|
|
} |
3686
|
|
|
|
3687
|
|
|
return $bean_name; |
3688
|
|
|
} |
3689
|
|
|
|
3690
|
|
|
function checkAuthUserStatus() |
3691
|
|
|
{ |
3692
|
|
|
|
3693
|
|
|
//authUserStatus(); |
3694
|
|
|
} |
3695
|
|
|
|
3696
|
|
|
/** |
3697
|
|
|
* This function returns an array of phpinfo() results that can be parsed and |
3698
|
|
|
* used to figure out what version we run, what modules are compiled in, etc. |
3699
|
|
|
* |
3700
|
|
|
* @param $level int info level constant (1,2,4,8...64); |
3701
|
|
|
* |
3702
|
|
|
* @return $returnInfo array array of info about the PHP environment |
3703
|
|
|
* |
3704
|
|
|
* @author original by "code at adspeed dot com" Fron php.net |
3705
|
|
|
* @author customized for Sugar by Chris N. |
3706
|
|
|
*/ |
3707
|
|
|
function getPhpInfo($level = -1) |
3708
|
|
|
{ |
3709
|
|
|
/* Name (constant) Value Description |
3710
|
|
|
INFO_GENERAL 1 The configuration line, php.ini location, build date, Web Server, System and more. |
3711
|
|
|
INFO_CREDITS 2 PHP Credits. See also phpcredits(). |
3712
|
|
|
INFO_CONFIGURATION 4 Current Local and Master values for PHP directives. See also ini_get(). |
3713
|
|
|
INFO_MODULES 8 Loaded modules and their respective settings. See also get_loaded_extensions(). |
3714
|
|
|
INFO_ENVIRONMENT 16 Environment Variable information that's also available in $_ENV. |
3715
|
|
|
INFO_VARIABLES 32 Shows all predefined variables from EGPCS (Environment, GET, POST, Cookie, Server). |
3716
|
|
|
INFO_LICENSE 64 PHP License information. See also the license FAQ. |
3717
|
|
|
INFO_ALL -1 Shows all of the above. This is the default value. |
3718
|
|
|
*/ |
3719
|
|
|
ob_start(); |
3720
|
|
|
phpinfo($level); |
3721
|
|
|
$phpinfo = ob_get_contents(); |
3722
|
|
|
ob_end_clean(); |
3723
|
|
|
|
3724
|
|
|
$phpinfo = strip_tags($phpinfo, '<h1><h2><th><td>'); |
3725
|
|
|
$phpinfo = preg_replace('/<th[^>]*>([^<]+)<\/th>/', '<info>\\1</info>', $phpinfo); |
3726
|
|
|
$phpinfo = preg_replace('/<td[^>]*>([^<]+)<\/td>/', '<info>\\1</info>', $phpinfo); |
3727
|
|
|
$parsedInfo = preg_split('/(<h.?>[^<]+<\/h.>)/', $phpinfo, -1, PREG_SPLIT_DELIM_CAPTURE); |
3728
|
|
|
$match = ''; |
3729
|
|
|
$version = ''; |
3730
|
|
|
$returnInfo = array(); |
3731
|
|
|
|
3732
|
|
|
if (preg_match('/<h1 class\=\"p\">PHP Version ([^<]+)<\/h1>/', $phpinfo, $version)) { |
3733
|
|
|
$returnInfo['PHP Version'] = $version[1]; |
3734
|
|
|
} |
3735
|
|
|
|
3736
|
|
|
for ($i = 1; $i < count($parsedInfo); ++$i) { |
|
|
|
|
3737
|
|
|
if (preg_match('/<h.>([^<]+)<\/h.>/', $parsedInfo[$i], $match)) { |
3738
|
|
|
$vName = trim($match[1]); |
3739
|
|
|
$parsedInfo2 = explode("\n", $parsedInfo[$i + 1]); |
3740
|
|
|
|
3741
|
|
|
foreach ($parsedInfo2 as $vOne) { |
3742
|
|
|
$vPat = '<info>([^<]+)<\/info>'; |
3743
|
|
|
$vPat3 = "/$vPat\s*$vPat\s*$vPat/"; |
3744
|
|
|
$vPat2 = "/$vPat\s*$vPat/"; |
3745
|
|
|
|
3746
|
|
|
if (preg_match($vPat3, $vOne, $match)) { // 3cols |
3747
|
|
|
$returnInfo[$vName][trim($match[1])] = array(trim($match[2]), trim($match[3])); |
3748
|
|
|
} elseif (preg_match($vPat2, $vOne, $match)) { // 2cols |
3749
|
|
|
$returnInfo[$vName][trim($match[1])] = trim($match[2]); |
3750
|
|
|
} |
3751
|
|
|
} |
3752
|
|
|
} elseif (true) { |
3753
|
|
|
} |
3754
|
|
|
} |
3755
|
|
|
|
3756
|
|
|
return $returnInfo; |
3757
|
|
|
} |
3758
|
|
|
|
3759
|
|
|
/** |
3760
|
|
|
* This function will take a string that has tokens like {0}, {1} and will replace |
3761
|
|
|
* those tokens with the args provided. |
3762
|
|
|
* |
3763
|
|
|
* @param $format string to format |
3764
|
|
|
* @param $args args to replace |
3765
|
|
|
* |
3766
|
|
|
* @return $result a formatted string |
3767
|
|
|
*/ |
3768
|
|
|
function string_format($format, $args) |
3769
|
|
|
{ |
3770
|
2 |
|
$result = $format; |
3771
|
|
|
|
3772
|
|
|
/* Bug47277 fix. |
3773
|
|
|
* If args array has only one argument, and it's empty, so empty single quotes are used '' . That's because |
3774
|
|
|
* IN () fails and IN ('') works. |
3775
|
|
|
*/ |
3776
|
2 |
|
if (count($args) == 1) { |
3777
|
2 |
|
reset($args); |
3778
|
2 |
|
$singleArgument = current($args); |
3779
|
2 |
|
if (empty($singleArgument)) { |
3780
|
1 |
|
return str_replace('{0}', "''", $result); |
3781
|
|
|
} |
3782
|
|
|
} |
3783
|
|
|
/* End of fix */ |
3784
|
|
|
|
3785
|
1 |
|
for ($i = 0; $i < count($args); ++$i) { |
|
|
|
|
3786
|
1 |
|
$result = str_replace('{'.$i.'}', $args[$i], $result); |
3787
|
|
|
} |
3788
|
|
|
|
3789
|
1 |
|
return $result; |
3790
|
|
|
} |
3791
|
|
|
|
3792
|
|
|
/** |
3793
|
|
|
* Generate a string for displaying a unique identifier that is composed |
3794
|
|
|
* of a system_id and number. This is use to allow us to generate quote |
3795
|
|
|
* numbers using a DB auto-increment key from offline clients and still |
3796
|
|
|
* have the number be unique (since it is modified by the system_id. |
3797
|
|
|
* |
3798
|
|
|
* @param $num of bean |
3799
|
|
|
* @param $system_id from system |
3800
|
|
|
* |
3801
|
|
|
* @return $result a formatted string |
3802
|
|
|
*/ |
3803
|
|
|
function format_number_display($num, $system_id) |
3804
|
|
|
{ |
3805
|
|
|
global $sugar_config; |
3806
|
|
|
if (isset($num) && !empty($num)) { |
3807
|
|
|
$num = unformat_number($num); |
3808
|
|
|
if (isset($system_id) && $system_id == 1) { |
3809
|
|
|
return sprintf('%d', $num); |
3810
|
|
|
} else { |
3811
|
|
|
return sprintf('%d-%d', $num, $system_id); |
3812
|
|
|
} |
3813
|
|
|
} |
3814
|
|
|
} |
3815
|
|
|
|
3816
|
|
|
function checkLoginUserStatus() |
3817
|
|
|
{ |
3818
|
|
|
} |
3819
|
|
|
|
3820
|
|
|
/** |
3821
|
|
|
* This function will take a number and system_id and format. |
3822
|
|
|
* |
3823
|
|
|
* @param $url URL containing host to append port |
3824
|
|
|
* @param $port the port number - if '' is passed, no change to url |
3825
|
|
|
* |
3826
|
|
|
* @return $resulturl the new URL with the port appended to the host |
3827
|
|
|
*/ |
3828
|
|
|
function appendPortToHost($url, $port) |
3829
|
|
|
{ |
3830
|
|
|
$resulturl = $url; |
3831
|
|
|
|
3832
|
|
|
// if no port, don't change the url |
3833
|
|
|
if ($port != '') { |
3834
|
|
|
$split = explode('/', $url); |
3835
|
|
|
//check if it starts with http, in case they didn't include that in url |
3836
|
|
|
if (str_begin($url, 'http')) { |
3837
|
|
|
//third index ($split[2]) will be the host |
3838
|
|
|
$split[2] .= ':'.$port; |
3839
|
|
|
} else { |
3840
|
|
|
// otherwise assumed to start with host name |
3841
|
|
|
|
3842
|
|
|
//first index ($split[0]) will be the host |
3843
|
|
|
$split[0] .= ':'.$port; |
3844
|
|
|
} |
3845
|
|
|
|
3846
|
|
|
$resulturl = implode('/', $split); |
3847
|
|
|
} |
3848
|
|
|
|
3849
|
|
|
return $resulturl; |
3850
|
|
|
} |
3851
|
|
|
|
3852
|
|
|
/** |
3853
|
|
|
* Singleton to return JSON object. |
3854
|
|
|
* |
3855
|
|
|
* @return JSON object |
3856
|
|
|
*/ |
3857
|
|
|
function getJSONobj() |
3858
|
|
|
{ |
3859
|
9 |
|
static $json = null; |
3860
|
9 |
|
if (!isset($json)) { |
3861
|
1 |
|
require_once 'include/JSON.php'; |
3862
|
1 |
|
$json = new JSON(JSON_LOOSE_TYPE); |
3863
|
|
|
} |
3864
|
|
|
|
3865
|
9 |
|
return $json; |
3866
|
|
|
} |
3867
|
|
|
|
3868
|
|
|
require_once 'include/utils/db_utils.php'; |
3869
|
|
|
|
3870
|
|
|
/** |
3871
|
|
|
* Set default php.ini settings for entry points. |
3872
|
|
|
*/ |
3873
|
|
|
function setPhpIniSettings() |
3874
|
|
|
{ |
3875
|
|
|
// zlib module |
3876
|
|
|
// Bug 37579 - Comment out force enabling zlib.output_compression, since it can cause problems on certain hosts |
3877
|
|
|
/* |
3878
|
|
|
if(function_exists('gzclose') && headers_sent() == false) { |
3879
|
|
|
ini_set('zlib.output_compression', 1); |
3880
|
|
|
} |
3881
|
|
|
*/ |
3882
|
|
|
// mbstring module |
3883
|
|
|
//nsingh: breaks zip/unzip functionality. Commenting out 4/23/08 |
3884
|
|
|
|
3885
|
|
|
/*if(function_exists('mb_strlen')) { |
3886
|
|
|
ini_set('mbstring.func_overload', 7); |
3887
|
|
|
ini_set('mbstring.internal_encoding', 'UTF-8'); |
3888
|
|
|
}*/ |
3889
|
|
|
|
3890
|
|
|
// http://us3.php.net/manual/en/ref.pcre.php#ini.pcre.backtrack-limit |
3891
|
|
|
// starting with 5.2.0, backtrack_limit breaks JSON decoding |
3892
|
|
|
$backtrack_limit = ini_get('pcre.backtrack_limit'); |
3893
|
|
|
if (!empty($backtrack_limit)) { |
3894
|
|
|
ini_set('pcre.backtrack_limit', '-1'); |
3895
|
|
|
} |
3896
|
|
|
} |
3897
|
|
|
|
3898
|
|
|
/** |
3899
|
|
|
* Identical to sugarArrayMerge but with some speed improvements and used specifically to merge |
3900
|
|
|
* language files. Language file merges do not need to account for null values so we can get some |
3901
|
|
|
* performance increases by using this specialized function. Note this merge function does not properly |
3902
|
|
|
* handle null values. |
3903
|
|
|
* |
3904
|
|
|
* @param $gimp |
3905
|
|
|
* @param $dom |
3906
|
|
|
* |
3907
|
|
|
* @return array |
3908
|
|
|
*/ |
3909
|
|
|
function sugarLangArrayMerge($gimp, $dom) |
3910
|
|
|
{ |
3911
|
20 |
|
if (is_array($gimp) && is_array($dom)) { |
3912
|
20 |
|
foreach ($dom as $domKey => $domVal) { |
3913
|
20 |
|
if (isset($gimp[$domKey])) { |
3914
|
20 |
|
if (is_array($domVal)) { |
3915
|
|
|
$tempArr = array(); |
3916
|
|
|
foreach ($domVal as $domArrKey => $domArrVal) { |
3917
|
|
|
$tempArr[$domArrKey] = $domArrVal; |
3918
|
|
|
} |
3919
|
|
|
foreach ($gimp[$domKey] as $gimpArrKey => $gimpArrVal) { |
3920
|
|
|
if (!isset($tempArr[$gimpArrKey])) { |
3921
|
|
|
$tempArr[$gimpArrKey] = $gimpArrVal; |
3922
|
|
|
} |
3923
|
|
|
} |
3924
|
|
|
$gimp[$domKey] = $tempArr; |
3925
|
|
|
} else { |
3926
|
20 |
|
$gimp[$domKey] = $domVal; |
3927
|
|
|
} |
3928
|
|
|
} else { |
3929
|
20 |
|
$gimp[$domKey] = $domVal; |
3930
|
|
|
} |
3931
|
|
|
} |
3932
|
|
|
} // if the passed value for gimp isn't an array, then return the $dom |
3933
|
|
|
elseif (is_array($dom)) { |
3934
|
|
|
return $dom; |
3935
|
|
|
} |
3936
|
|
|
|
3937
|
20 |
|
return $gimp; |
3938
|
|
|
} |
3939
|
|
|
|
3940
|
|
|
/** |
3941
|
|
|
* like array_merge() but will handle array elements that are themselves arrays; |
3942
|
|
|
* PHP's version just overwrites the element with the new one. |
3943
|
|
|
* |
3944
|
|
|
* @internal Note that this function deviates from the internal array_merge() |
3945
|
|
|
* functions in that it does does not treat numeric keys differently |
3946
|
|
|
* than string keys. Additionally, it deviates from |
3947
|
|
|
* array_merge_recursive() by not creating an array when like values |
3948
|
|
|
* found. |
3949
|
|
|
* |
3950
|
|
|
* @param array gimp the array whose values will be overloaded |
3951
|
|
|
* @param array dom the array whose values will pwn the gimp's |
3952
|
|
|
* |
3953
|
|
|
* @return array beaten gimp |
3954
|
|
|
*/ |
3955
|
|
|
function sugarArrayMerge($gimp, $dom) |
3956
|
|
|
{ |
3957
|
|
|
if (is_array($gimp) && is_array($dom)) { |
3958
|
|
|
foreach ($dom as $domKey => $domVal) { |
3959
|
|
|
if (array_key_exists($domKey, $gimp)) { |
3960
|
|
|
if (is_array($domVal)) { |
3961
|
|
|
$tempArr = array(); |
3962
|
|
|
foreach ($domVal as $domArrKey => $domArrVal) { |
3963
|
|
|
$tempArr[$domArrKey] = $domArrVal; |
3964
|
|
|
} |
3965
|
|
|
foreach ($gimp[$domKey] as $gimpArrKey => $gimpArrVal) { |
3966
|
|
|
if (!array_key_exists($gimpArrKey, $tempArr)) { |
3967
|
|
|
$tempArr[$gimpArrKey] = $gimpArrVal; |
3968
|
|
|
} |
3969
|
|
|
} |
3970
|
|
|
$gimp[$domKey] = $tempArr; |
3971
|
|
|
} else { |
3972
|
|
|
$gimp[$domKey] = $domVal; |
3973
|
|
|
} |
3974
|
|
|
} else { |
3975
|
|
|
$gimp[$domKey] = $domVal; |
3976
|
|
|
} |
3977
|
|
|
} |
3978
|
|
|
} // if the passed value for gimp isn't an array, then return the $dom |
3979
|
|
|
elseif (is_array($dom)) { |
3980
|
|
|
return $dom; |
3981
|
|
|
} |
3982
|
|
|
|
3983
|
|
|
return $gimp; |
3984
|
|
|
} |
3985
|
|
|
|
3986
|
|
|
/** |
3987
|
|
|
* Similiar to sugarArrayMerge except arrays of N depth are merged. |
3988
|
|
|
* |
3989
|
|
|
* @param array gimp the array whose values will be overloaded |
3990
|
|
|
* @param array dom the array whose values will pwn the gimp's |
3991
|
|
|
* |
3992
|
|
|
* @return array beaten gimp |
3993
|
|
|
*/ |
3994
|
|
|
function sugarArrayMergeRecursive($gimp, $dom) |
3995
|
|
|
{ |
3996
|
27 |
|
if (is_array($gimp) && is_array($dom)) { |
3997
|
27 |
|
foreach ($dom as $domKey => $domVal) { |
3998
|
27 |
|
if (array_key_exists($domKey, $gimp)) { |
3999
|
17 |
|
if (is_array($domVal) && is_array($gimp[$domKey])) { |
4000
|
|
|
$gimp[$domKey] = sugarArrayMergeRecursive($gimp[$domKey], $domVal); |
4001
|
|
|
} else { |
4002
|
17 |
|
$gimp[$domKey] = $domVal; |
4003
|
|
|
} |
4004
|
|
|
} else { |
4005
|
27 |
|
$gimp[$domKey] = $domVal; |
4006
|
|
|
} |
4007
|
|
|
} |
4008
|
|
|
} // if the passed value for gimp isn't an array, then return the $dom |
4009
|
|
|
elseif (is_array($dom)) { |
4010
|
|
|
return $dom; |
4011
|
|
|
} |
4012
|
|
|
|
4013
|
27 |
|
return $gimp; |
4014
|
|
|
} |
4015
|
|
|
|
4016
|
|
|
/** |
4017
|
|
|
* finds the correctly working versions of PHP-JSON. |
4018
|
|
|
* |
4019
|
|
|
* @return bool True if NOT found or WRONG version |
4020
|
|
|
*/ |
4021
|
|
|
function returnPhpJsonStatus() |
4022
|
|
|
{ |
4023
|
|
|
if (function_exists('json_encode')) { |
4024
|
|
|
$phpInfo = getPhpInfo(8); |
4025
|
|
|
|
4026
|
|
|
return version_compare($phpInfo['json']['json version'], '1.1.1', '<'); |
4027
|
|
|
} |
4028
|
|
|
|
4029
|
|
|
return true; // not found |
4030
|
|
|
} |
4031
|
|
|
|
4032
|
|
|
/** |
4033
|
|
|
* getTrackerSubstring. |
4034
|
|
|
* |
4035
|
|
|
* Returns a [number]-char or less string for the Tracker to display in the header |
4036
|
|
|
* based on the tracker_max_display_length setting in config.php. If not set, |
4037
|
|
|
* or invalid length, then defaults to 15 for COM editions, 30 for others. |
4038
|
|
|
* |
4039
|
|
|
* @param string name field for a given Object |
4040
|
|
|
* |
4041
|
|
|
* @return string [number]-char formatted string if length of string exceeds the max allowed |
4042
|
|
|
*/ |
4043
|
|
|
function getTrackerSubstring($name) |
4044
|
|
|
{ |
4045
|
|
|
static $max_tracker_item_length; |
4046
|
|
|
|
4047
|
|
|
//Trim the name |
4048
|
|
|
$name = html_entity_decode($name, ENT_QUOTES, 'UTF-8'); |
4049
|
|
|
$strlen = function_exists('mb_strlen') ? mb_strlen($name) : strlen($name); |
4050
|
|
|
|
4051
|
|
|
global $sugar_config; |
4052
|
|
|
|
4053
|
|
|
if (!isset($max_tracker_item_length)) { |
4054
|
|
|
if (isset($sugar_config['tracker_max_display_length'])) { |
4055
|
|
|
$max_tracker_item_length = (is_int($sugar_config['tracker_max_display_length']) && $sugar_config['tracker_max_display_length'] > 0 && $sugar_config['tracker_max_display_length'] < 50) ? $sugar_config['tracker_max_display_length'] : 15; |
4056
|
|
|
} else { |
4057
|
|
|
$max_tracker_item_length = 15; |
4058
|
|
|
} |
4059
|
|
|
} |
4060
|
|
|
|
4061
|
|
|
if ($strlen > $max_tracker_item_length) { |
4062
|
|
|
$chopped = function_exists('mb_substr') ? mb_substr($name, 0, $max_tracker_item_length - 3, 'UTF-8') : substr($name, 0, $max_tracker_item_length - 3); |
4063
|
|
|
$chopped .= '...'; |
4064
|
|
|
} else { |
4065
|
|
|
$chopped = $name; |
4066
|
|
|
} |
4067
|
|
|
|
4068
|
|
|
return $chopped; |
4069
|
|
|
} |
4070
|
|
|
|
4071
|
|
|
function generate_search_where($field_list = array(), $values = array(), &$bean, $add_custom_fields = false, $module = '') |
4072
|
|
|
{ |
4073
|
|
|
$where_clauses = array(); |
4074
|
|
|
$like_char = '%'; |
4075
|
|
|
$table_name = $bean->object_name; |
4076
|
|
|
foreach ($field_list[$module] as $field => $parms) { |
4077
|
|
|
if (isset($values[$field]) && $values[$field] != '') { |
4078
|
|
|
$operator = 'like'; |
4079
|
|
|
if (!empty($parms['operator'])) { |
4080
|
|
|
$operator = $parms['operator']; |
4081
|
|
|
} |
4082
|
|
|
if (is_array($values[$field])) { |
4083
|
|
|
$operator = 'in'; |
4084
|
|
|
$field_value = ''; |
4085
|
|
|
foreach ($values[$field] as $key => $val) { |
4086
|
|
|
if ($val != ' ' and $val != '') { |
4087
|
|
|
if (!empty($field_value)) { |
4088
|
|
|
$field_value .= ','; |
4089
|
|
|
} |
4090
|
|
|
$field_value .= "'".$GLOBALS['db']->quote($val)."'"; |
4091
|
|
|
} |
4092
|
|
|
} |
4093
|
|
|
} else { |
4094
|
|
|
$field_value = $GLOBALS['db']->quote($values[$field]); |
4095
|
|
|
} |
4096
|
|
|
//set db_fields array. |
4097
|
|
|
if (!isset($parms['db_field'])) { |
4098
|
|
|
$parms['db_field'] = array($field); |
4099
|
|
|
} |
4100
|
|
|
if (isset($parms['my_items']) and $parms['my_items'] == true) { |
4101
|
|
|
global $current_user; |
4102
|
|
|
$field_value = $GLOBALS['db']->quote($current_user->id); |
4103
|
|
|
$operator = '='; |
4104
|
|
|
} |
4105
|
|
|
|
4106
|
|
|
$where = ''; |
4107
|
|
|
$itr = 0; |
4108
|
|
|
if ($field_value != '') { |
4109
|
|
|
foreach ($parms['db_field'] as $db_field) { |
4110
|
|
|
if (strstr($db_field, '.') === false) { |
4111
|
|
|
$db_field = $bean->table_name.'.'.$db_field; |
4112
|
|
|
} |
4113
|
|
|
if ($GLOBALS['db']->supports('case_sensitive') && isset($parms['query_type']) && $parms['query_type'] == 'case_insensitive') { |
4114
|
|
|
$db_field = 'upper('.$db_field.')'; |
4115
|
|
|
$field_value = strtoupper($field_value); |
4116
|
|
|
} |
4117
|
|
|
|
4118
|
|
|
++$itr; |
4119
|
|
|
if (!empty($where)) { |
4120
|
|
|
$where .= ' OR '; |
4121
|
|
|
} |
4122
|
|
|
switch (strtolower($operator)) { |
4123
|
|
|
case 'like' : |
4124
|
|
|
$where .= $db_field." like '".$field_value.$like_char."'"; |
4125
|
|
|
break; |
4126
|
|
|
case 'in': |
4127
|
|
|
$where .= $db_field.' in ('.$field_value.')'; |
4128
|
|
|
break; |
4129
|
|
|
case '=': |
4130
|
|
|
$where .= $db_field." = '".$field_value."'"; |
4131
|
|
|
break; |
4132
|
|
|
} |
4133
|
|
|
} |
4134
|
|
|
} |
4135
|
|
|
if (!empty($where)) { |
4136
|
|
|
if ($itr > 1) { |
4137
|
|
|
array_push($where_clauses, '( '.$where.' )'); |
4138
|
|
|
} else { |
4139
|
|
|
array_push($where_clauses, $where); |
4140
|
|
|
} |
4141
|
|
|
} |
4142
|
|
|
} |
4143
|
|
|
} |
4144
|
|
|
if ($add_custom_fields) { |
4145
|
|
|
require_once 'modules/DynamicFields/DynamicField.php'; |
4146
|
|
|
$bean->setupCustomFields($module); |
4147
|
|
|
$bean->custom_fields->setWhereClauses($where_clauses); |
4148
|
|
|
} |
4149
|
|
|
|
4150
|
|
|
return $where_clauses; |
4151
|
|
|
} |
4152
|
|
|
|
4153
|
|
|
function add_quotes($str) |
4154
|
|
|
{ |
4155
|
|
|
return "'{$str}'"; |
4156
|
|
|
} |
4157
|
|
|
|
4158
|
|
|
/** |
4159
|
|
|
* This function will rebuild the config file. |
4160
|
|
|
* |
4161
|
|
|
* @param $sugar_config |
4162
|
|
|
* @param $sugar_version |
4163
|
|
|
* |
4164
|
|
|
* @return bool true if successful |
4165
|
|
|
*/ |
4166
|
|
|
function rebuildConfigFile($sugar_config, $sugar_version) |
4167
|
|
|
{ |
4168
|
|
|
// add defaults to missing values of in-memory sugar_config |
4169
|
|
|
$sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config); |
4170
|
|
|
// need to override version with default no matter what |
4171
|
|
|
$sugar_config['sugar_version'] = $sugar_version; |
4172
|
|
|
|
4173
|
|
|
ksort($sugar_config); |
4174
|
|
|
|
4175
|
|
|
if (write_array_to_file('sugar_config', $sugar_config, 'config.php')) { |
4176
|
|
|
return true; |
4177
|
|
|
} else { |
4178
|
|
|
return false; |
4179
|
|
|
} |
4180
|
|
|
} |
4181
|
|
|
|
4182
|
|
|
/** |
4183
|
|
|
* Loads clean configuration, not overridden by config_override.php. |
4184
|
|
|
* |
4185
|
|
|
* @return array |
4186
|
|
|
*/ |
4187
|
|
|
function loadCleanConfig() |
4188
|
|
|
{ |
4189
|
|
|
$sugar_config = array(); |
4190
|
|
|
require 'config.php'; |
4191
|
|
|
|
4192
|
|
|
return $sugar_config; |
4193
|
|
|
} |
4194
|
|
|
|
4195
|
|
|
/** |
4196
|
|
|
* getJavascriptSiteURL |
4197
|
|
|
* This function returns a URL for the client javascript calls to access |
4198
|
|
|
* the site. It uses $_SERVER['HTTP_REFERER'] in the event that Proxy servers |
4199
|
|
|
* are used to access the site. Thus, the hostname in the URL returned may |
4200
|
|
|
* not always match that of $sugar_config['site_url']. Basically, the |
4201
|
|
|
* assumption is that however the user accessed the website is how they |
4202
|
|
|
* will continue to with subsequent javascript requests. If the variable |
4203
|
|
|
* $_SERVER['HTTP_REFERER'] is not found then we default to old algorithm. |
4204
|
|
|
* |
4205
|
|
|
* @return $site_url The url used to refer to the website |
4206
|
|
|
*/ |
4207
|
|
|
function getJavascriptSiteURL() |
4208
|
|
|
{ |
4209
|
|
|
global $sugar_config; |
4210
|
|
|
if (!empty($_SERVER['HTTP_REFERER'])) { |
4211
|
|
|
$url = parse_url($_SERVER['HTTP_REFERER']); |
4212
|
|
|
$replacement_url = $url['scheme'].'://'.$url['host']; |
4213
|
|
|
if (!empty($url['port'])) { |
4214
|
|
|
$replacement_url .= ':'.$url['port']; |
4215
|
|
|
} |
4216
|
|
|
$site_url = preg_replace('/^http[s]?\:\/\/[^\/]+/', $replacement_url, $sugar_config['site_url']); |
4217
|
|
|
} else { |
4218
|
|
|
$site_url = preg_replace('/^http(s)?\:\/\/[^\/]+/', 'http$1://'.$_SERVER['HTTP_HOST'], $sugar_config['site_url']); |
4219
|
|
|
if (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443') { |
4220
|
|
|
$site_url = preg_replace('/^http\:/', 'https:', $site_url); |
4221
|
|
|
} |
4222
|
|
|
} |
4223
|
|
|
$GLOBALS['log']->debug('getJavascriptSiteURL(), site_url='.$site_url); |
4224
|
|
|
|
4225
|
|
|
return $site_url; |
4226
|
|
|
} |
4227
|
|
|
|
4228
|
|
|
// works nicely with array_map() -- can be used to wrap single quotes around each element in an array |
4229
|
|
|
function add_squotes($str) |
4230
|
|
|
{ |
4231
|
|
|
return "'".$str."'"; |
4232
|
|
|
} |
4233
|
|
|
|
4234
|
|
|
// recursive function to count the number of levels within an array |
4235
|
|
|
function array_depth($array, $depth_count = -1, $depth_array = array()) |
4236
|
|
|
{ |
4237
|
|
|
++$depth_count; |
4238
|
|
|
if (is_array($array)) { |
4239
|
|
|
foreach ($array as $key => $value) { |
4240
|
|
|
$depth_array[] = array_depth($value, $depth_count); |
4241
|
|
|
} |
4242
|
|
|
} else { |
4243
|
|
|
return $depth_count; |
4244
|
|
|
} |
4245
|
|
|
foreach ($depth_array as $value) { |
4246
|
|
|
$depth_count = $value > $depth_count ? $value : $depth_count; |
4247
|
|
|
} |
4248
|
|
|
|
4249
|
|
|
return $depth_count; |
4250
|
|
|
} |
4251
|
|
|
|
4252
|
|
|
/** |
4253
|
|
|
* Creates a new Group User. |
4254
|
|
|
* |
4255
|
|
|
* @param string $name Name of Group User |
4256
|
|
|
* |
4257
|
|
|
* @return string GUID of new Group User |
4258
|
|
|
*/ |
4259
|
|
|
function createGroupUser($name) |
4260
|
|
|
{ |
4261
|
|
|
$group = new User(); |
4262
|
|
|
$group->user_name = $name; |
4263
|
|
|
$group->last_name = $name; |
4264
|
|
|
$group->is_group = 1; |
4265
|
|
|
$group->deleted = 0; |
4266
|
|
|
$group->status = 'Active'; // cn: bug 6711 |
4267
|
|
|
$group->setPreference('timezone', TimeDate::userTimezone()); |
4268
|
|
|
$group->save(); |
4269
|
|
|
|
4270
|
|
|
return $group->id; |
4271
|
|
|
} |
4272
|
|
|
|
4273
|
|
|
/* |
4274
|
|
|
* Helper function to locate an icon file given only a name |
4275
|
|
|
* Searches through the various paths for the file |
4276
|
|
|
* @param string iconFileName The filename of the icon |
4277
|
|
|
* @return string Relative pathname of the located icon, or '' if not found |
4278
|
|
|
*/ |
4279
|
|
|
|
4280
|
|
|
function _getIcon($iconFileName) |
4281
|
|
|
{ |
4282
|
|
|
$iconName = "icon_{$iconFileName}.gif"; |
4283
|
|
|
$iconFound = SugarThemeRegistry::current()->getImageURL($iconName, false); |
4284
|
|
|
|
4285
|
|
|
//First try un-ucfirst-ing the icon name |
4286
|
|
|
if (empty($iconFound)) { |
4287
|
|
|
$iconName = 'icon_'.strtolower(substr($iconFileName, 0, 1)).substr($iconFileName, 1).'.gif'; |
4288
|
|
|
} |
4289
|
|
|
$iconFound = SugarThemeRegistry::current()->getImageURL($iconName, false); |
4290
|
|
|
|
4291
|
|
|
//Next try removing the icon prefix |
4292
|
|
|
if (empty($iconFound)) { |
4293
|
|
|
$iconName = "{$iconFileName}.gif"; |
4294
|
|
|
} |
4295
|
|
|
$iconFound = SugarThemeRegistry::current()->getImageURL($iconName, false); |
4296
|
|
|
|
4297
|
|
|
if (empty($iconFound)) { |
4298
|
|
|
$iconName = ''; |
4299
|
|
|
} |
4300
|
|
|
|
4301
|
|
|
return $iconName; |
4302
|
|
|
} |
4303
|
|
|
|
4304
|
|
|
/** |
4305
|
|
|
* Function to grab the correct icon image for Studio. |
4306
|
|
|
* |
4307
|
|
|
* @param string $iconFileName Name of the icon file |
4308
|
|
|
* @param string $altfilename Name of a fallback icon file (displayed if the imagefilename doesn't exist) |
4309
|
|
|
* @param string $width Width of image |
4310
|
|
|
* @param string $height Height of image |
4311
|
|
|
* @param string $align Alignment of image |
4312
|
|
|
* @param string $alt Alt tag of image |
4313
|
|
|
* |
4314
|
|
|
* @return string $string <img> tag with corresponding image |
4315
|
|
|
*/ |
4316
|
|
|
function getStudioIcon($iconFileName = '', $altFileName = '', $width = '48', $height = '48', $align = 'baseline', $alt = '') |
4317
|
|
|
{ |
4318
|
|
|
global $app_strings, $theme; |
4319
|
|
|
|
4320
|
|
|
$iconName = _getIcon($iconFileName); |
4321
|
|
|
if (empty($iconName)) { |
4322
|
|
|
$iconName = _getIcon($altFileName); |
4323
|
|
|
if (empty($iconName)) { |
4324
|
|
|
return $app_strings['LBL_NO_IMAGE']; |
4325
|
|
|
} |
4326
|
|
|
} |
4327
|
|
|
|
4328
|
|
|
return SugarThemeRegistry::current()->getImage($iconName, "align=\"$align\" border=\"0\"", $width, $height); |
4329
|
|
|
} |
4330
|
|
|
|
4331
|
|
|
/** |
4332
|
|
|
* Function to grab the correct icon image for Dashlets Dialog. |
4333
|
|
|
* |
4334
|
|
|
* @param string $filename Location of the icon file |
4335
|
|
|
* @param string $module Name of the module to fall back onto if file does not exist |
4336
|
|
|
* @param string $width Width of image |
4337
|
|
|
* @param string $height Height of image |
4338
|
|
|
* @param string $align Alignment of image |
4339
|
|
|
* @param string $alt Alt tag of image |
4340
|
|
|
* |
4341
|
|
|
* @return string $string <img> tag with corresponding image |
4342
|
|
|
*/ |
4343
|
|
|
function get_dashlets_dialog_icon($module = '', $width = '32', $height = '32', $align = 'absmiddle', $alt = '') |
4344
|
|
|
{ |
4345
|
|
|
global $app_strings, $theme; |
4346
|
|
|
$iconName = _getIcon($module.'_32'); |
4347
|
|
|
if (empty($iconName)) { |
4348
|
|
|
$iconName = _getIcon($module); |
4349
|
|
|
} |
4350
|
|
|
if (empty($iconName)) { |
4351
|
|
|
return $app_strings['LBL_NO_IMAGE']; |
4352
|
|
|
} |
4353
|
|
|
|
4354
|
|
|
return SugarThemeRegistry::current()->getImage($iconName, "align=\"$align\" border=\"0\"", $width, $height); |
4355
|
|
|
} |
4356
|
|
|
|
4357
|
|
|
// works nicely to change UTF8 strings that are html entities - good for PDF conversions |
4358
|
|
|
function html_entity_decode_utf8($string) |
4359
|
|
|
{ |
4360
|
|
|
static $trans_tbl; |
4361
|
|
|
// replace numeric entities |
4362
|
|
|
//php will have issues with numbers with leading zeros, so do not include them in what we send to code2utf. |
4363
|
|
|
$string = preg_replace('~�*([0-9a-f]+);~ei', 'code2utf(hexdec("\\1"))', $string); |
4364
|
|
|
$string = preg_replace('~�*([0-9]+);~e', 'code2utf(\\1)', $string); |
4365
|
|
|
// replace literal entities |
4366
|
|
|
if (!isset($trans_tbl)) { |
4367
|
|
|
$trans_tbl = array(); |
4368
|
|
|
foreach (get_html_translation_table(HTML_ENTITIES) as $val => $key) { |
4369
|
|
|
$trans_tbl[$key] = utf8_encode($val); |
4370
|
|
|
} |
4371
|
|
|
} |
4372
|
|
|
|
4373
|
|
|
return strtr($string, $trans_tbl); |
4374
|
|
|
} |
4375
|
|
|
|
4376
|
|
|
// Returns the utf string corresponding to the unicode value |
4377
|
|
|
function code2utf($num) |
4378
|
|
|
{ |
4379
|
|
|
if ($num < 128) { |
4380
|
|
|
return chr($num); |
4381
|
|
|
} |
4382
|
|
|
if ($num < 2048) { |
4383
|
|
|
return chr(($num >> 6) + 192).chr(($num & 63) + 128); |
4384
|
|
|
} |
4385
|
|
|
if ($num < 65536) { |
4386
|
|
|
return chr(($num >> 12) + 224).chr((($num >> 6) & 63) + 128).chr(($num & 63) + 128); |
4387
|
|
|
} |
4388
|
|
|
if ($num < 2097152) { |
4389
|
|
|
return chr(($num >> 18) + 240).chr((($num >> 12) & 63) + 128).chr((($num >> 6) & 63) + 128).chr(($num & 63) + 128); |
4390
|
|
|
} |
4391
|
|
|
|
4392
|
|
|
return ''; |
4393
|
|
|
} |
4394
|
|
|
|
4395
|
|
|
function str_split_php4($string, $length = 1) |
4396
|
|
|
{ |
4397
|
|
|
$string_length = strlen($string); |
4398
|
|
|
$return = array(); |
4399
|
|
|
$cursor = 0; |
4400
|
|
|
if ($length > $string_length) { |
4401
|
|
|
// use the string_length as the string is shorter than the length |
4402
|
|
|
$length = $string_length; |
4403
|
|
|
} |
4404
|
|
|
for ($cursor = 0; $cursor < $string_length; $cursor = $cursor + $length) { |
4405
|
|
|
$return[] = substr($string, $cursor, $length); |
4406
|
|
|
} |
4407
|
|
|
|
4408
|
|
|
return $return; |
4409
|
|
|
} |
4410
|
|
|
|
4411
|
|
|
if (version_compare(phpversion(), '5.0.0', '<')) { |
4412
|
|
|
function str_split($string, $length = 1) |
4413
|
|
|
{ |
4414
|
|
|
return str_split_php4($string, $length); |
4415
|
|
|
} |
4416
|
|
|
} |
4417
|
|
|
|
4418
|
|
|
/* |
4419
|
|
|
* @deprecated use DBManagerFactory::isFreeTDS |
4420
|
|
|
*/ |
4421
|
|
|
function is_freetds() |
4422
|
|
|
{ |
4423
|
|
|
return DBManagerFactory::isFreeTDS(); |
4424
|
|
|
} |
4425
|
|
|
|
4426
|
|
|
/** |
4427
|
|
|
* Chart dashlet helper function that returns the correct CSS file, dependent on the current theme. |
4428
|
|
|
* |
4429
|
|
|
* @todo this won't work completely right until we impliment css compression and combination |
4430
|
|
|
* for now, we'll just include the last css file found. |
4431
|
|
|
* |
4432
|
|
|
* @return chart.css file to use |
4433
|
|
|
*/ |
4434
|
|
|
function chartStyle() |
4435
|
|
|
{ |
4436
|
|
|
return SugarThemeRegistry::current()->getCSSURL('chart.css'); |
4437
|
|
|
} |
4438
|
|
|
|
4439
|
|
|
/** |
4440
|
|
|
* Chart dashlet helper functions that returns the correct XML color file for charts, |
4441
|
|
|
* dependent on the current theme. |
4442
|
|
|
* |
4443
|
|
|
* @return sugarColors.xml to use |
4444
|
|
|
*/ |
4445
|
|
|
function chartColors() |
4446
|
|
|
{ |
4447
|
|
|
if (SugarThemeRegistry::current()->getCSSURL('sugarColors.xml') == '') { |
4448
|
|
|
return SugarThemeRegistry::current()->getImageURL('sugarColors.xml'); |
4449
|
|
|
} |
4450
|
|
|
|
4451
|
|
|
return SugarThemeRegistry::current()->getCSSURL('sugarColors.xml'); |
4452
|
|
|
} |
4453
|
|
|
|
4454
|
|
|
/* End Chart Dashlet helper functions */ |
4455
|
|
|
|
4456
|
|
|
/** |
4457
|
|
|
* This function is designed to set up the php enviroment |
4458
|
|
|
* for AJAX requests. |
4459
|
|
|
*/ |
4460
|
|
|
function ajaxInit() |
4461
|
|
|
{ |
4462
|
|
|
ini_set('display_errors', 'false'); |
4463
|
|
|
} |
4464
|
|
|
|
4465
|
|
|
/** |
4466
|
|
|
* Returns an absolute path from the given path, determining if it is relative or absolute. |
4467
|
|
|
* |
4468
|
|
|
* @param string $path |
4469
|
|
|
* |
4470
|
|
|
* @return string |
4471
|
|
|
*/ |
4472
|
|
|
function getAbsolutePath( |
4473
|
|
|
$path, |
4474
|
|
|
$currentServer = false |
4475
|
|
|
) { |
4476
|
|
|
$path = trim($path); |
4477
|
|
|
|
4478
|
|
|
// try to match absolute paths like \\server\share, /directory or c:\ |
4479
|
|
|
if ((substr($path, 0, 2) == '\\\\') |
4480
|
|
|
|| ($path[0] == '/') |
4481
|
|
|
|| preg_match('/^[A-z]:/i', $path) |
4482
|
|
|
|| $currentServer |
4483
|
|
|
) { |
4484
|
|
|
return $path; |
4485
|
|
|
} |
4486
|
|
|
|
4487
|
|
|
return getcwd().'/'.$path; |
4488
|
|
|
} |
4489
|
|
|
|
4490
|
|
|
/** |
4491
|
|
|
* Returns the bean object of the given module. |
4492
|
|
|
* |
4493
|
|
|
* @deprecated use SugarModule::loadBean() instead |
4494
|
|
|
* |
4495
|
|
|
* @param string $module |
4496
|
|
|
* |
4497
|
|
|
* @return object |
4498
|
|
|
*/ |
4499
|
|
|
function loadBean( |
4500
|
|
|
$module |
4501
|
|
|
) { |
4502
|
5 |
|
return SugarModule::get($module)->loadBean(); |
4503
|
|
|
} |
4504
|
|
|
|
4505
|
|
|
/** |
4506
|
|
|
* Returns true if the application is being accessed on a touch screen interface ( like an iPad ). |
4507
|
|
|
*/ |
4508
|
|
|
function isTouchScreen() |
4509
|
|
|
{ |
4510
|
|
|
$ua = empty($_SERVER['HTTP_USER_AGENT']) ? 'undefined' : strtolower($_SERVER['HTTP_USER_AGENT']); |
4511
|
|
|
|
4512
|
|
|
// first check if we have forced use of the touch enhanced interface |
4513
|
|
|
if (isset($_COOKIE['touchscreen']) && $_COOKIE['touchscreen'] == '1') { |
4514
|
|
|
return true; |
4515
|
|
|
} |
4516
|
|
|
|
4517
|
|
|
// next check if we should use the touch interface with our device |
4518
|
|
|
if (strpos($ua, 'ipad') !== false) { |
4519
|
|
|
return true; |
4520
|
|
|
} |
4521
|
|
|
|
4522
|
|
|
return false; |
4523
|
|
|
} |
4524
|
|
|
|
4525
|
|
|
/** |
4526
|
|
|
* Returns the shortcut keys to access the shortcut links. Shortcut |
4527
|
|
|
* keys vary depending on browser versions and operating systems. |
4528
|
|
|
* |
4529
|
|
|
* @return string value of the shortcut keys |
4530
|
|
|
*/ |
4531
|
|
|
function get_alt_hot_key() |
4532
|
|
|
{ |
4533
|
|
|
$ua = ''; |
4534
|
|
|
if (isset($_SERVER['HTTP_USER_AGENT'])) { |
4535
|
|
|
$ua = strtolower($_SERVER['HTTP_USER_AGENT']); |
4536
|
|
|
} |
4537
|
|
|
$isMac = strpos($ua, 'mac') !== false; |
4538
|
|
|
$isLinux = strpos($ua, 'linux') !== false; |
4539
|
|
|
|
4540
|
|
|
if (!$isMac && !$isLinux && strpos($ua, 'mozilla') !== false) { |
4541
|
|
|
if (preg_match('/firefox\/(\d)?\./', $ua, $matches)) { |
4542
|
|
|
return $matches[1] < 2 ? 'Alt+' : 'Alt+Shift+'; |
4543
|
|
|
} |
4544
|
|
|
} |
4545
|
|
|
|
4546
|
|
|
return $isMac ? 'Ctrl+' : 'Alt+'; |
4547
|
|
|
} |
4548
|
|
|
|
4549
|
|
|
function can_start_session() |
4550
|
|
|
{ |
4551
|
1 |
|
if (!empty($_GET['PHPSESSID'])) { |
4552
|
|
|
return true; |
4553
|
|
|
} |
4554
|
1 |
|
$session_id = session_id(); |
4555
|
|
|
|
4556
|
1 |
|
return empty($session_id) ? true : false; |
4557
|
|
|
} |
4558
|
|
|
|
4559
|
|
|
function load_link_class($properties) |
4560
|
|
|
{ |
4561
|
128 |
|
$class = 'Link2'; |
4562
|
128 |
|
if (!empty($properties['link_class']) && !empty($properties['link_file'])) { |
4563
|
|
|
require_once $properties['link_file']; |
4564
|
|
|
$class = $properties['link_class']; |
4565
|
|
|
} |
4566
|
|
|
|
4567
|
128 |
|
return $class; |
4568
|
|
|
} |
4569
|
|
|
|
4570
|
|
|
function inDeveloperMode() |
4571
|
|
|
{ |
4572
|
800 |
|
return isset($GLOBALS['sugar_config']['developerMode']) && $GLOBALS['sugar_config']['developerMode']; |
4573
|
|
|
} |
4574
|
|
|
|
4575
|
|
|
/** |
4576
|
|
|
* Filter the protocol list for inbound email accounts. |
4577
|
|
|
* |
4578
|
|
|
* @param array $protocol |
4579
|
|
|
*/ |
4580
|
|
|
function filterInboundEmailPopSelection($protocol) |
4581
|
|
|
{ |
4582
|
|
|
if (!isset($GLOBALS['sugar_config']['allow_pop_inbound']) || !$GLOBALS['sugar_config']['allow_pop_inbound']) { |
4583
|
|
|
if (isset($protocol['pop3'])) { |
4584
|
|
|
unset($protocol['pop3']); |
4585
|
|
|
} |
4586
|
|
|
} else { |
4587
|
|
|
$protocol['pop3'] = 'POP3'; |
4588
|
|
|
} |
4589
|
|
|
|
4590
|
|
|
return $protocol; |
4591
|
|
|
} |
4592
|
|
|
|
4593
|
|
|
/** |
4594
|
|
|
* The function is used because currently we are not supporting mbstring.func_overload |
4595
|
|
|
* 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. |
4596
|
|
|
* 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. |
4597
|
|
|
* |
4598
|
|
|
* @returns the substred strings. |
4599
|
|
|
*/ |
4600
|
|
|
function sugar_substr($string, $length, $charset = 'UTF-8') |
4601
|
|
|
{ |
4602
|
|
|
if (mb_strlen($string, $charset) > $length) { |
4603
|
|
|
$string = trim(mb_substr(trim($string), 0, $length, $charset)); |
4604
|
|
|
} |
4605
|
|
|
|
4606
|
|
|
return $string; |
4607
|
|
|
} |
4608
|
|
|
|
4609
|
|
|
/** |
4610
|
|
|
* The function is used because on FastCGI enviroment, the ucfirst(Chinese Characters) will produce bad charcters. |
4611
|
|
|
* This will work even without setting the mbstring.*encoding. |
4612
|
|
|
*/ |
4613
|
|
|
function sugar_ucfirst($string, $charset = 'UTF-8') |
4614
|
|
|
{ |
4615
|
|
|
return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_substr($string, 1, mb_strlen($string), $charset); |
4616
|
|
|
} |
4617
|
|
|
|
4618
|
|
|
/** |
4619
|
|
|
* |
4620
|
|
|
*/ |
4621
|
|
|
function unencodeMultienum($string) |
4622
|
|
|
{ |
4623
|
|
|
if (is_array($string)) { |
4624
|
|
|
return $string; |
4625
|
|
|
} |
4626
|
|
|
if (substr($string, 0, 1) == '^' && substr($string, -1) == '^') { |
4627
|
|
|
$string = substr(substr($string, 1), 0, strlen($string) - 2); |
4628
|
|
|
} |
4629
|
|
|
|
4630
|
|
|
return explode('^,^', $string); |
4631
|
|
|
} |
4632
|
|
|
|
4633
|
|
|
function encodeMultienumValue($arr) |
4634
|
|
|
{ |
4635
|
|
|
if (!is_array($arr)) { |
4636
|
|
|
return $arr; |
4637
|
|
|
} |
4638
|
|
|
|
4639
|
|
|
if (empty($arr)) { |
4640
|
|
|
return ''; |
4641
|
|
|
} |
4642
|
|
|
|
4643
|
|
|
$string = '^'.implode('^,^', $arr).'^'; |
4644
|
|
|
|
4645
|
|
|
return $string; |
4646
|
|
|
} |
4647
|
|
|
|
4648
|
|
|
/** |
4649
|
|
|
* create_export_query is used for export and massupdate |
4650
|
|
|
* We haven't handle the these fields: $field['type'] == 'relate' && isset($field['link'] |
4651
|
|
|
* This function will correct the where clause and output necessary join condition for them. |
4652
|
|
|
* |
4653
|
|
|
* @param $module : the module name |
4654
|
|
|
* @param $searchFields : searchFields which is got after $searchForm->populateFromArray() |
4655
|
|
|
* @param $where : where clauses |
4656
|
|
|
* |
4657
|
|
|
* @return array |
4658
|
|
|
*/ |
4659
|
|
|
function create_export_query_relate_link_patch($module, $searchFields, $where) |
4660
|
|
|
{ |
4661
|
|
|
if (file_exists('modules/'.$module.'/SearchForm.html')) { |
4662
|
|
|
$ret_array['where'] = $where; |
4663
|
|
|
|
4664
|
|
|
return $ret_array; |
4665
|
|
|
} |
4666
|
|
|
$seed = BeanFactory::getBean($module); |
4667
|
|
|
foreach ($seed->field_defs as $name => $field) { |
4668
|
|
|
if ($field['type'] == 'relate' && isset($field['link']) && !empty($searchFields[$name]['value'])) { |
4669
|
|
|
$seed->load_relationship($field['link']); |
4670
|
|
|
$params = array(); |
4671
|
|
|
if (empty($join_type)) { |
4672
|
|
|
$params['join_type'] = ' LEFT JOIN '; |
4673
|
|
|
} else { |
4674
|
|
|
$params['join_type'] = $join_type; |
4675
|
|
|
} |
4676
|
|
|
if (isset($data['join_name'])) { |
4677
|
|
|
$params['join_table_alias'] = $field['join_name']; |
4678
|
|
|
} else { |
4679
|
|
|
$params['join_table_alias'] = 'join_'.$field['name']; |
4680
|
|
|
} |
4681
|
|
|
if (isset($data['join_link_name'])) { |
4682
|
|
|
$params['join_table_link_alias'] = $field['join_link_name']; |
4683
|
|
|
} else { |
4684
|
|
|
$params['join_table_link_alias'] = 'join_link_'.$field['name']; |
4685
|
|
|
} |
4686
|
|
|
$fieldLink = $field['link']; |
4687
|
|
|
$join = $seed->$fieldLink->getJoin($params, true); |
4688
|
|
|
$join_table_alias = 'join_'.$field['name']; |
4689
|
|
|
if (isset($field['db_concat_fields'])) { |
4690
|
|
|
$db_field = db_concat($join_table_alias, $field['db_concat_fields']); |
4691
|
|
|
$where = preg_replace('/'.$field['name'].'/', $db_field, $where); |
4692
|
|
|
} else { |
4693
|
|
|
$where = preg_replace('/(^|[\s(])'.$field['name'].'/', '${1}'.$join_table_alias.'.'.$field['rname'], $where); |
4694
|
|
|
} |
4695
|
|
|
} |
4696
|
|
|
} |
4697
|
|
|
$ret_array = array('where' => $where, 'join' => isset($join['join']) ? $join['join'] : ''); |
4698
|
|
|
|
4699
|
|
|
return $ret_array; |
4700
|
|
|
} |
4701
|
|
|
|
4702
|
|
|
/** |
4703
|
|
|
* We need to clear all the js cache files, including the js language files in serval places in MB. So I extract them into a util function here. |
4704
|
|
|
* |
4705
|
|
|
* @Depends on QuickRepairAndRebuild.php |
4706
|
|
|
* @Relate bug 30642 ,23177 |
4707
|
|
|
*/ |
4708
|
|
|
function clearAllJsAndJsLangFilesWithoutOutput() |
4709
|
|
|
{ |
4710
|
|
|
global $current_language, $mod_strings; |
4711
|
|
|
$MBmodStrings = $mod_strings; |
4712
|
|
|
$mod_strings = return_module_language($current_language, 'Administration'); |
4713
|
|
|
include_once 'modules/Administration/QuickRepairAndRebuild.php'; |
4714
|
|
|
$repair = new RepairAndClear(); |
4715
|
|
|
$repair->module_list = array(); |
4716
|
|
|
$repair->show_output = false; |
4717
|
|
|
$repair->clearJsLangFiles(); |
4718
|
|
|
$repair->clearJsFiles(); |
4719
|
|
|
$mod_strings = $MBmodStrings; |
4720
|
|
|
} |
4721
|
|
|
|
4722
|
|
|
/** |
4723
|
|
|
* This function will allow you to get a variable value from query string. |
4724
|
|
|
*/ |
4725
|
|
|
function getVariableFromQueryString($variable, $string) |
4726
|
|
|
{ |
4727
|
|
|
$matches = array(); |
4728
|
|
|
$number = preg_match("/{$variable}=([a-zA-Z0-9_-]+)[&]?/", $string, $matches); |
4729
|
|
|
if ($number) { |
4730
|
|
|
return $matches[1]; |
4731
|
|
|
} else { |
4732
|
|
|
return false; |
4733
|
|
|
} |
4734
|
|
|
} |
4735
|
|
|
|
4736
|
|
|
/** |
4737
|
|
|
* should_hide_iframes |
4738
|
|
|
* This is a helper method to determine whether or not to show iframes (My Sites) related |
4739
|
|
|
* information in the application. |
4740
|
|
|
* |
4741
|
|
|
* @return bool flag indicating whether or not iframes module should be hidden |
4742
|
|
|
*/ |
4743
|
|
|
function should_hide_iframes() |
4744
|
|
|
{ |
4745
|
|
|
//Remove the MySites module |
4746
|
|
|
if (file_exists('modules/iFrames/iFrame.php')) { |
4747
|
|
|
if (!class_exists('iFrame')) { |
4748
|
|
|
require_once 'modules/iFrames/iFrame.php'; |
4749
|
|
|
} |
4750
|
|
|
|
4751
|
|
|
return false; |
4752
|
|
|
} |
4753
|
|
|
|
4754
|
|
|
return true; |
4755
|
|
|
} |
4756
|
|
|
|
4757
|
|
|
/** |
4758
|
|
|
* Given a version such as 5.5.0RC1 return RC. If we have a version such as: 5.5 then return GA. |
4759
|
|
|
* |
4760
|
|
|
* @param string $version |
4761
|
|
|
* |
4762
|
|
|
* @return string RC, BETA, GA |
4763
|
|
|
*/ |
4764
|
|
|
function getVersionStatus($version) |
4765
|
|
|
{ |
4766
|
|
|
if (preg_match('/^[\d\.]+?([a-zA-Z]+?)[\d]*?$/si', $version, $matches)) { |
4767
|
|
|
return strtoupper($matches[1]); |
4768
|
|
|
} else { |
4769
|
|
|
return 'GA'; |
4770
|
|
|
} |
4771
|
|
|
} |
4772
|
|
|
|
4773
|
|
|
/** |
4774
|
|
|
* Return the numeric portion of a version. For example if passed 5.5.0RC1 then return 5.5. If given |
4775
|
|
|
* 5.5.1RC1 then return 5.5.1. |
4776
|
|
|
* |
4777
|
|
|
* @param string $version |
4778
|
|
|
* |
4779
|
|
|
* @return version |
4780
|
|
|
*/ |
4781
|
|
|
function getMajorMinorVersion($version) |
4782
|
|
|
{ |
4783
|
|
|
if (preg_match('/^([\d\.]+).*$/si', $version, $matches2)) { |
4784
|
|
|
$version = $matches2[1]; |
4785
|
|
|
$arr = explode('.', $version); |
4786
|
|
|
if (count($arr) > 2) { |
4787
|
|
|
if ($arr[2] == '0') { |
4788
|
|
|
$version = substr($version, 0, 3); |
4789
|
|
|
} |
4790
|
|
|
} |
4791
|
|
|
} |
4792
|
|
|
|
4793
|
|
|
return $version; |
4794
|
|
|
} |
4795
|
|
|
|
4796
|
|
|
/** |
4797
|
|
|
* Return string composed of seconds & microseconds of current time, without dots. |
4798
|
|
|
* |
4799
|
|
|
* @return string |
4800
|
|
|
*/ |
4801
|
|
|
function sugar_microtime() |
4802
|
|
|
{ |
4803
|
4 |
|
$now = explode(' ', microtime()); |
4804
|
4 |
|
$unique_id = $now[1].str_replace('.', '', $now[0]); |
4805
|
|
|
|
4806
|
4 |
|
return $unique_id; |
4807
|
|
|
} |
4808
|
|
|
|
4809
|
|
|
/** |
4810
|
|
|
* Extract urls from a piece of text. |
4811
|
|
|
* |
4812
|
|
|
* @param $string |
4813
|
|
|
* |
4814
|
|
|
* @return array of urls found in $string |
4815
|
|
|
*/ |
4816
|
|
|
function getUrls($string) |
4817
|
|
|
{ |
4818
|
1 |
|
$lines = explode('<br>', trim($string)); |
4819
|
1 |
|
$urls = array(); |
4820
|
1 |
|
foreach ($lines as $line) { |
4821
|
1 |
|
$regex = '/http?\:\/\/[^\" ]+/i'; |
4822
|
1 |
|
preg_match_all($regex, $line, $matches); |
4823
|
1 |
|
foreach ($matches[0] as $match) { |
4824
|
1 |
|
$urls[] = $match; |
4825
|
|
|
} |
4826
|
|
|
} |
4827
|
|
|
|
4828
|
1 |
|
return $urls; |
4829
|
|
|
} |
4830
|
|
|
|
4831
|
|
|
/** |
4832
|
|
|
* Sanitize image file from hostile content. |
4833
|
|
|
* |
4834
|
|
|
* @param string $path Image file |
4835
|
|
|
* @param bool $jpeg Accept only JPEGs? |
4836
|
|
|
*/ |
4837
|
|
|
function verify_image_file($path, $jpeg = false) |
4838
|
|
|
{ |
4839
|
|
|
if (function_exists('imagepng') && function_exists('imagejpeg') && function_exists('imagecreatefromstring')) { |
4840
|
|
|
$img = imagecreatefromstring(file_get_contents($path)); |
4841
|
|
|
if (!$img) { |
4842
|
|
|
return false; |
4843
|
|
|
} |
4844
|
|
|
$img_size = getimagesize($path); |
4845
|
|
|
$filetype = $img_size['mime']; |
4846
|
|
|
//if filetype is jpeg or if we are only allowing jpegs, create jpg image |
4847
|
|
|
if ($filetype == 'image/jpeg' || $jpeg) { |
4848
|
|
|
ob_start(); |
4849
|
|
|
imagejpeg($img); |
4850
|
|
|
$image = ob_get_clean(); |
4851
|
|
|
// not writing directly because imagejpeg does not work with streams |
4852
|
|
|
if (file_put_contents($path, $image)) { |
4853
|
|
|
return true; |
4854
|
|
|
} |
4855
|
|
|
} elseif ($filetype == 'image/png') { |
4856
|
|
|
// else if the filetype is png, create png |
4857
|
|
|
imagealphablending($img, true); |
4858
|
|
|
imagesavealpha($img, true); |
4859
|
|
|
ob_start(); |
4860
|
|
|
imagepng($img); |
4861
|
|
|
$image = ob_get_clean(); |
4862
|
|
|
if (file_put_contents($path, $image)) { |
4863
|
|
|
return true; |
4864
|
|
|
} |
4865
|
|
|
} else { |
4866
|
|
|
return false; |
4867
|
|
|
} |
4868
|
|
|
} else { |
4869
|
|
|
// check image manually |
4870
|
|
|
$fp = fopen($path, 'rb'); |
4871
|
|
|
if (!$fp) { |
4872
|
|
|
return false; |
4873
|
|
|
} |
4874
|
|
|
$data = ''; |
4875
|
|
|
// read the whole file in chunks |
4876
|
|
|
while (!feof($fp)) { |
4877
|
|
|
$data .= fread($fp, 8192); |
4878
|
|
|
} |
4879
|
|
|
|
4880
|
|
|
fclose($fp); |
4881
|
|
|
if (preg_match("/<(\?php|html|!doctype|script|body|head|plaintext|table|img |pre(>| )|frameset|iframe|object|link|base|style|font|applet|meta|center|form|isindex)/i", |
4882
|
|
|
$data, $m)) { |
4883
|
|
|
$GLOBALS['log']->fatal("Found {$m[0]} in $path, not allowing upload"); |
4884
|
|
|
|
4885
|
|
|
return false; |
4886
|
|
|
} |
4887
|
|
|
|
4888
|
|
|
return true; |
4889
|
|
|
} |
4890
|
|
|
|
4891
|
|
|
return false; |
4892
|
|
|
} |
4893
|
|
|
|
4894
|
|
|
/** |
4895
|
|
|
* Verify uploaded image |
4896
|
|
|
* Verifies that image has proper extension, MIME type and doesn't contain hostile content. |
4897
|
|
|
* |
4898
|
|
|
* @param string $path Image path |
4899
|
|
|
* @param bool $jpeg_only Accept only JPEGs? |
4900
|
|
|
*/ |
4901
|
|
|
function verify_uploaded_image($path, $jpeg_only = false) |
4902
|
|
|
{ |
4903
|
|
|
$supportedExtensions = array('jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg'); |
4904
|
|
|
if (!$jpeg_only) { |
4905
|
|
|
$supportedExtensions['png'] = 'image/png'; |
4906
|
|
|
} |
4907
|
|
|
|
4908
|
|
|
if (!file_exists($path) || !is_file($path)) { |
4909
|
|
|
return false; |
4910
|
|
|
} |
4911
|
|
|
|
4912
|
|
|
$img_size = getimagesize($path); |
4913
|
|
|
$filetype = $img_size['mime']; |
4914
|
|
|
$tmpArray = explode('.', $path); |
4915
|
|
|
$ext = end($tmpArray); |
4916
|
|
|
if (substr_count('..', $path) > 0 || ($ext !== $path && !isset($supportedExtensions[strtolower($ext)])) || |
4917
|
|
|
!in_array($filetype, array_values($supportedExtensions)) |
4918
|
|
|
) { |
4919
|
|
|
return false; |
4920
|
|
|
} |
4921
|
|
|
|
4922
|
|
|
return verify_image_file($path, $jpeg_only); |
4923
|
|
|
} |
4924
|
|
|
|
4925
|
|
|
function cmp_beans($a, $b) |
4926
|
|
|
{ |
4927
|
|
|
global $sugar_web_service_order_by; |
4928
|
|
|
//If the order_by field is not valid, return 0; |
4929
|
|
|
if (empty($sugar_web_service_order_by) || !isset($a->$sugar_web_service_order_by) || !isset($b->$sugar_web_service_order_by)) { |
4930
|
|
|
return 0; |
4931
|
|
|
} |
4932
|
|
|
if (is_object($a->$sugar_web_service_order_by) || is_object($b->$sugar_web_service_order_by) |
4933
|
|
|
|| is_array($a->$sugar_web_service_order_by) || is_array($b->$sugar_web_service_order_by) |
4934
|
|
|
) { |
4935
|
|
|
return 0; |
4936
|
|
|
} |
4937
|
|
|
if ($a->$sugar_web_service_order_by < $b->$sugar_web_service_order_by) { |
4938
|
|
|
return -1; |
4939
|
|
|
} else { |
4940
|
|
|
return 1; |
4941
|
|
|
} |
4942
|
|
|
} |
4943
|
|
|
|
4944
|
|
|
function order_beans($beans, $field_name) |
4945
|
|
|
{ |
4946
|
|
|
//Since php 5.2 doesn't include closures, we must use a global to pass the order field to cmp_beans. |
4947
|
|
|
global $sugar_web_service_order_by; |
4948
|
|
|
$sugar_web_service_order_by = $field_name; |
4949
|
|
|
usort($beans, 'cmp_beans'); |
4950
|
|
|
|
4951
|
|
|
return $beans; |
4952
|
|
|
} |
4953
|
|
|
|
4954
|
|
|
/** |
4955
|
|
|
* Return search like string |
4956
|
|
|
* This function takes a user input string and returns a string that contains wild card(s) that can be used in db query. |
4957
|
|
|
* |
4958
|
|
|
* @param string $str string to be searched |
4959
|
|
|
* @param string $like_char Database like character, usually '%' |
4960
|
|
|
* |
4961
|
|
|
* @return string Returns a string to be searched in db query |
4962
|
|
|
*/ |
4963
|
|
|
function sql_like_string($str, $like_char, $wildcard = '%', $appendWildcard = true) |
4964
|
|
|
{ |
4965
|
|
|
|
4966
|
|
|
// override default wildcard character |
4967
|
|
|
if (isset($GLOBALS['sugar_config']['search_wildcard_char']) && |
4968
|
|
|
strlen($GLOBALS['sugar_config']['search_wildcard_char']) == 1 |
4969
|
|
|
) { |
4970
|
|
|
$wildcard = $GLOBALS['sugar_config']['search_wildcard_char']; |
4971
|
|
|
} |
4972
|
|
|
|
4973
|
|
|
// add wildcard at the beginning of the search string |
4974
|
|
|
if (isset($GLOBALS['sugar_config']['search_wildcard_infront']) && |
4975
|
|
|
$GLOBALS['sugar_config']['search_wildcard_infront'] == true |
4976
|
|
|
) { |
4977
|
|
|
if (substr($str, 0, 1) != $wildcard) { |
4978
|
|
|
$str = $wildcard.$str; |
4979
|
|
|
} |
4980
|
|
|
} |
4981
|
|
|
|
4982
|
|
|
// add wildcard at the end of search string (default) |
4983
|
|
|
if ($appendWildcard) { |
4984
|
|
|
if (substr($str, -1) != $wildcard) { |
4985
|
|
|
$str .= $wildcard; |
4986
|
|
|
} |
4987
|
|
|
} |
4988
|
|
|
|
4989
|
|
|
return str_replace($wildcard, $like_char, $str); |
4990
|
|
|
} |
4991
|
|
|
|
4992
|
|
|
//check to see if custom utils exists |
4993
|
|
|
if (file_exists('custom/include/custom_utils.php')) { |
4994
|
|
|
include_once 'custom/include/custom_utils.php'; |
4995
|
|
|
} |
4996
|
|
|
|
4997
|
|
|
//check to see if custom utils exists in Extension framework |
4998
|
|
|
if (file_exists('custom/application/Ext/Utils/custom_utils.ext.php')) { |
4999
|
|
|
include_once 'custom/application/Ext/Utils/custom_utils.ext.php'; |
5000
|
|
|
} |
5001
|
|
|
/** |
5002
|
|
|
* @param $input - the input string to sanitize |
5003
|
|
|
* @param int $quotes - use quotes |
5004
|
|
|
* @param string $charset - the default charset |
5005
|
|
|
* @param bool $remove - strip tags or not |
5006
|
|
|
* |
5007
|
|
|
* @return string - the sanitized string |
5008
|
|
|
*/ |
5009
|
|
|
function sanitize($input, $quotes = ENT_QUOTES, $charset = 'UTF-8', $remove = false) |
5010
|
|
|
{ |
5011
|
|
|
return htmlentities($input, $quotes, $charset); |
5012
|
|
|
} |
5013
|
|
|
|
5014
|
|
|
/** |
5015
|
|
|
* @return string - the full text search engine name |
5016
|
|
|
*/ |
5017
|
|
|
function getFTSEngineType() |
5018
|
|
|
{ |
5019
|
|
|
if (isset($GLOBALS['sugar_config']['full_text_engine']) && is_array($GLOBALS['sugar_config']['full_text_engine'])) { |
5020
|
|
|
foreach ($GLOBALS['sugar_config']['full_text_engine'] as $name => $defs) { |
5021
|
|
|
return $name; |
5022
|
|
|
} |
5023
|
|
|
} |
5024
|
|
|
|
5025
|
|
|
return ''; |
5026
|
|
|
} |
5027
|
|
|
|
5028
|
|
|
/** |
5029
|
|
|
* @param string $optionName - name of the option to be retrieved from app_list_strings |
5030
|
|
|
* |
5031
|
|
|
* @return array - the array to be used in option element |
5032
|
|
|
*/ |
5033
|
|
|
function getFTSBoostOptions($optionName) |
5034
|
|
|
{ |
5035
|
|
|
if (isset($GLOBALS['app_list_strings'][$optionName])) { |
5036
|
|
|
return $GLOBALS['app_list_strings'][$optionName]; |
5037
|
|
|
} else { |
5038
|
|
|
return array(); |
5039
|
|
|
} |
5040
|
|
|
} |
5041
|
|
|
|
5042
|
|
|
/** |
5043
|
|
|
* utf8_recursive_encode. |
5044
|
|
|
* |
5045
|
|
|
* This function walks through an Array and recursively calls utf8_encode on the |
5046
|
|
|
* values of each of the elements. |
5047
|
|
|
* |
5048
|
|
|
* @param $data Array of data to encode |
5049
|
|
|
* |
5050
|
|
|
* @return utf8 encoded Array data |
5051
|
|
|
*/ |
5052
|
|
|
function utf8_recursive_encode($data) |
5053
|
|
|
{ |
5054
|
|
|
$result = array(); |
5055
|
|
|
foreach ($data as $key => $val) { |
5056
|
|
|
if (is_array($val)) { |
5057
|
|
|
$result[$key] = utf8_recursive_encode($val); |
5058
|
|
|
} else { |
5059
|
|
|
$result[$key] = utf8_encode($val); |
5060
|
|
|
} |
5061
|
|
|
} |
5062
|
|
|
|
5063
|
|
|
return $result; |
5064
|
|
|
} |
5065
|
|
|
|
5066
|
|
|
/** |
5067
|
|
|
* get_language_header. |
5068
|
|
|
* |
5069
|
|
|
* This is a utility function for 508 Compliance. It returns the lang=[Current Language] text string used |
5070
|
|
|
* inside the <html> tag. If no current language is specified, it defaults to lang='en'. |
5071
|
|
|
* |
5072
|
|
|
* @return string The lang=[Current Language] markup to insert into the <html> tag |
5073
|
|
|
*/ |
5074
|
|
|
function get_language_header() |
5075
|
|
|
{ |
5076
|
4 |
|
return isset($GLOBALS['current_language']) ? "lang='{$GLOBALS['current_language']}'" : "lang='en'"; |
5077
|
|
|
} |
5078
|
|
|
|
5079
|
|
|
/** |
5080
|
|
|
* get_custom_file_if_exists. |
5081
|
|
|
* |
5082
|
|
|
* This function handles the repetitive code we have where we first check if a file exists in the |
5083
|
|
|
* custom directory to determine whether we should load it, require it, include it, etc. This function returns the |
5084
|
|
|
* path of the custom file if it exists. It basically checks if custom/{$file} exists and returns this path if so; |
5085
|
|
|
* otherwise it return $file |
5086
|
|
|
* |
5087
|
|
|
* @param $file String of filename to check |
5088
|
|
|
* |
5089
|
|
|
* @return $file String of filename including custom directory if found |
5090
|
|
|
*/ |
5091
|
|
|
function get_custom_file_if_exists($file) |
5092
|
|
|
{ |
5093
|
7 |
|
return file_exists("custom/{$file}") ? "custom/{$file}" : $file; |
5094
|
|
|
} |
5095
|
|
|
|
5096
|
|
|
/** |
5097
|
|
|
* get_help_url. |
5098
|
|
|
* |
5099
|
|
|
* This will return the URL used to redirect the user to the help documentation. |
5100
|
|
|
* It can be overriden completely by setting the custom_help_url or partially by setting the custom_help_base_url |
5101
|
|
|
* in config.php or config_override.php. |
5102
|
|
|
* |
5103
|
|
|
* @param string $send_edition |
5104
|
|
|
* @param string $send_version |
5105
|
|
|
* @param string $send_lang |
5106
|
|
|
* @param string $send_module |
5107
|
|
|
* @param string $send_action |
5108
|
|
|
* @param string $dev_status |
5109
|
|
|
* @param string $send_key |
5110
|
|
|
* @param string $send_anchor |
5111
|
|
|
* |
5112
|
|
|
* @return string the completed help URL |
5113
|
|
|
*/ |
5114
|
|
|
function get_help_url($send_edition = '', $send_version = '', $send_lang = '', $send_module = '', $send_action = '', $dev_status = '', $send_key = '', $send_anchor = '') |
5115
|
|
|
{ |
5116
|
|
|
global $sugar_config; |
5117
|
|
|
|
5118
|
|
|
if (!empty($sugar_config['custom_help_url'])) { |
5119
|
|
|
$sendUrl = $sugar_config['custom_help_url']; |
5120
|
|
|
} else { |
5121
|
|
|
if (!empty($sugar_config['custom_help_base_url'])) { |
5122
|
|
|
$baseUrl = $sugar_config['custom_help_base_url']; |
5123
|
|
|
} else { |
5124
|
|
|
$baseUrl = 'http://www.sugarcrm.com/crm/product_doc.php'; |
5125
|
|
|
} |
5126
|
|
|
$sendUrl = $baseUrl."?edition={$send_edition}&version={$send_version}&lang={$send_lang}&module={$send_module}&help_action={$send_action}&status={$dev_status}&key={$send_key}"; |
5127
|
|
|
if (!empty($send_anchor)) { |
5128
|
|
|
$sendUrl .= '&anchor='.$send_anchor; |
5129
|
|
|
} |
5130
|
|
|
} |
5131
|
|
|
|
5132
|
|
|
return $sendUrl; |
5133
|
|
|
} |
5134
|
|
|
|
5135
|
|
|
/** |
5136
|
|
|
* generateETagHeader. |
5137
|
|
|
* |
5138
|
|
|
* This function generates the necessary cache headers for using ETags with dynamic content. You |
5139
|
|
|
* simply have to generate the ETag, pass it in, and the function handles the rest. |
5140
|
|
|
* |
5141
|
|
|
* @param string $etag ETag to use for this content. |
5142
|
|
|
*/ |
5143
|
|
|
function generateETagHeader($etag) |
5144
|
|
|
{ |
5145
|
1 |
|
header('cache-control:'); |
5146
|
|
|
header('Expires: '); |
5147
|
|
|
header('ETag: '.$etag); |
5148
|
|
|
header('Pragma:'); |
5149
|
|
|
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { |
5150
|
|
|
if ($etag == $_SERVER['HTTP_IF_NONE_MATCH']) { |
5151
|
|
|
ob_clean(); |
5152
|
|
|
header('Status: 304 Not Modified'); |
5153
|
|
|
header('HTTP/1.0 304 Not Modified'); |
5154
|
|
|
die(); |
5155
|
|
|
} |
5156
|
|
|
} |
5157
|
|
|
} |
5158
|
|
|
|
5159
|
|
|
/** |
5160
|
|
|
* getReportNameTranslation. |
5161
|
|
|
* |
5162
|
|
|
* Translates the report name if a translation exists, |
5163
|
|
|
* otherwise just returns the name |
5164
|
|
|
* |
5165
|
|
|
* @param string $reportName |
5166
|
|
|
* |
5167
|
|
|
* @return string translated report name |
5168
|
|
|
*/ |
5169
|
|
|
function getReportNameTranslation($reportName) |
5170
|
|
|
{ |
5171
|
|
|
global $current_language; |
5172
|
|
|
|
5173
|
|
|
// Used for translating reports |
5174
|
|
|
$mod_strings = return_module_language($current_language, 'Reports'); |
5175
|
|
|
|
5176
|
|
|
// Search for the report name in the default language and get the key |
5177
|
|
|
$key = array_search($reportName, return_module_language('', 'Reports')); |
5178
|
|
|
|
5179
|
|
|
// If the key was found, use it to get a translation, otherwise just use report name |
5180
|
|
|
if (!empty($key)) { |
5181
|
|
|
$title = $mod_strings[$key]; |
5182
|
|
|
} else { |
5183
|
|
|
$title = $reportName; |
5184
|
|
|
} |
5185
|
|
|
|
5186
|
|
|
return $title; |
5187
|
|
|
} |
5188
|
|
|
|
5189
|
|
|
/** |
5190
|
|
|
* Remove vars marked senstitive from array. |
5191
|
|
|
* |
5192
|
|
|
* @param array $defs |
5193
|
|
|
* @param SugarBean|array $data |
5194
|
|
|
* |
5195
|
|
|
* @return mixed $data without sensitive fields |
5196
|
|
|
*/ |
5197
|
|
|
function clean_sensitive_data($defs, $data) |
5198
|
|
|
{ |
5199
|
|
|
foreach ($defs as $field => $def) { |
5200
|
|
|
if (!empty($def['sensitive'])) { |
5201
|
|
|
if (is_array($data)) { |
5202
|
|
|
$data[$field] = ''; |
5203
|
|
|
} |
5204
|
|
|
if ($data instanceof SugarBean) { |
5205
|
|
|
$data->$field = ''; |
5206
|
|
|
} |
5207
|
|
|
} |
5208
|
|
|
} |
5209
|
|
|
|
5210
|
|
|
return $data; |
5211
|
|
|
} |
5212
|
|
|
|
5213
|
|
|
/** |
5214
|
|
|
* Return relations with labels for duplicates. |
5215
|
|
|
*/ |
5216
|
|
|
function getDuplicateRelationListWithTitle($def, $var_def, $module) |
5217
|
|
|
{ |
5218
|
|
|
global $current_language; |
5219
|
|
|
$select_array = array_unique($def); |
5220
|
|
|
if (count($select_array) < count($def)) { |
5221
|
|
|
$temp_module_strings = return_module_language($current_language, $module); |
5222
|
|
|
$temp_duplicate_array = array_diff_assoc($def, $select_array); |
5223
|
|
|
$temp_duplicate_array = array_merge($temp_duplicate_array, array_intersect($select_array, $temp_duplicate_array)); |
5224
|
|
|
|
5225
|
|
|
foreach ($temp_duplicate_array as $temp_key => $temp_value) { |
5226
|
|
|
// Don't add duplicate relationships |
5227
|
|
|
if (!empty($var_def[$temp_key]['relationship']) && array_key_exists($var_def[$temp_key]['relationship'], $select_array)) { |
5228
|
|
|
continue; |
5229
|
|
|
} |
5230
|
|
|
$select_array[$temp_key] = $temp_value; |
5231
|
|
|
} |
5232
|
|
|
|
5233
|
|
|
// Add the relationship name for easier recognition |
5234
|
|
|
foreach ($select_array as $key => $value) { |
5235
|
|
|
$select_array[$key] .= ' ('.$key.')'; |
5236
|
|
|
} |
5237
|
|
|
} |
5238
|
|
|
asort($select_array); |
5239
|
|
|
|
5240
|
|
|
return $select_array; |
5241
|
|
|
} |
5242
|
|
|
|
5243
|
|
|
/** |
5244
|
|
|
* Gets the list of "*type_display*". |
5245
|
|
|
* |
5246
|
|
|
* @return array |
5247
|
|
|
*/ |
5248
|
|
|
function getTypeDisplayList() |
5249
|
|
|
{ |
5250
|
|
|
return array('record_type_display', 'parent_type_display', 'record_type_display_notes'); |
5251
|
|
|
} |
5252
|
|
|
|
5253
|
|
|
/** |
5254
|
|
|
* Breaks given string into substring according |
5255
|
|
|
* to 'db_concat_fields' from field definition |
5256
|
|
|
* and assigns values to corresponding properties |
5257
|
|
|
* of bean. |
5258
|
|
|
* |
5259
|
|
|
* @param SugarBean $bean |
5260
|
|
|
* @param array $fieldDef |
5261
|
|
|
* @param string $value |
5262
|
|
|
*/ |
5263
|
|
|
function assignConcatenatedValue(SugarBean $bean, $fieldDef, $value) |
5264
|
|
|
{ |
5265
|
|
|
$valueParts = explode(' ', $value); |
5266
|
|
|
$valueParts = array_filter($valueParts); |
5267
|
|
|
$fieldNum = count($fieldDef['db_concat_fields']); |
5268
|
|
|
|
5269
|
|
|
if (count($valueParts) == 1 && $fieldDef['db_concat_fields'] == array('first_name', 'last_name')) { |
5270
|
|
|
$bean->last_name = $value; |
5271
|
|
|
} // elseif ($fieldNum >= count($valueParts)) |
5272
|
|
|
else { |
5273
|
|
|
for ($i = 0; $i < $fieldNum; ++$i) { |
5274
|
|
|
$fieldValue = array_shift($valueParts); |
5275
|
|
|
$fieldName = $fieldDef['db_concat_fields'][$i]; |
5276
|
|
|
$bean->$fieldName = $fieldValue !== false ? $fieldValue : ''; |
5277
|
|
|
} |
5278
|
|
|
|
5279
|
|
|
if (!empty($valueParts)) { |
5280
|
|
|
$bean->$fieldName .= ' '.implode(' ', $valueParts); |
5281
|
|
|
} |
5282
|
|
|
} |
5283
|
|
|
} |
5284
|
|
|
|
5285
|
|
|
/** |
5286
|
|
|
* Performs unserialization. Accepts all types except Objects. |
5287
|
|
|
* |
5288
|
|
|
* @param string $value Serialized value of any type except Object |
5289
|
|
|
* |
5290
|
|
|
* @return mixed False if Object, converted value for other cases |
5291
|
|
|
*/ |
5292
|
|
|
function sugar_unserialize($value) |
5293
|
|
|
{ |
5294
|
1 |
|
preg_match('/[oc]:\d+:/i', $value, $matches); |
5295
|
|
|
|
5296
|
1 |
|
if (count($matches)) { |
5297
|
|
|
return false; |
5298
|
|
|
} |
5299
|
|
|
|
5300
|
1 |
|
return unserialize($value); |
5301
|
|
|
} |
5302
|
|
|
|
5303
|
|
|
define('DEFAULT_UTIL_SUITE_ENCODING', 'UTF-8'); |
5304
|
|
|
|
5305
|
|
|
function suite_strlen($input, $encoding = DEFAULT_UTIL_SUITE_ENCODING) |
5306
|
|
|
{ |
5307
|
|
|
if (function_exists('mb_strlen')) { |
5308
|
|
|
return mb_strlen($input, $encoding); |
5309
|
|
|
} else { |
5310
|
|
|
return strlen($input); |
5311
|
|
|
} |
5312
|
|
|
} |
5313
|
|
|
|
5314
|
|
|
function suite_substr($input, $start, $length = null, $encoding = DEFAULT_UTIL_SUITE_ENCODING) |
5315
|
|
|
{ |
5316
|
|
|
if (function_exists('mb_substr')) { |
5317
|
|
|
return mb_substr($input, $start, $length, $encoding); |
5318
|
|
|
} else { |
5319
|
|
|
return substr($input, $start, $length); |
5320
|
|
|
} |
5321
|
|
|
} |
5322
|
|
|
|
5323
|
|
|
function suite_strtoupper($input, $encoding = DEFAULT_UTIL_SUITE_ENCODING) |
5324
|
|
|
{ |
5325
|
|
|
if (function_exists('mb_strtoupper')) { |
5326
|
|
|
return mb_strtoupper($input, $encoding); |
5327
|
|
|
} else { |
5328
|
|
|
return strtoupper($input); |
5329
|
|
|
} |
5330
|
|
|
} |
5331
|
|
|
|
5332
|
|
|
function suite_strtolower($input, $encoding = DEFAULT_UTIL_SUITE_ENCODING) |
5333
|
|
|
{ |
5334
|
|
|
if (function_exists('mb_strtolower')) { |
5335
|
|
|
return mb_strtolower($input, $encoding); |
5336
|
|
|
} else { |
5337
|
|
|
return strtolower($input); |
5338
|
|
|
} |
5339
|
|
|
} |
5340
|
|
|
|
5341
|
|
|
function suite_strpos($haystack, $needle, $offset = 0, $encoding = DEFAULT_UTIL_SUITE_ENCODING) |
5342
|
|
|
{ |
5343
|
|
|
if (function_exists('mb_strpos')) { |
5344
|
|
|
return mb_strpos($haystack, $needle, $offset, $encoding); |
5345
|
|
|
} else { |
5346
|
|
|
return strpos($haystack, $needle, $offset); |
5347
|
|
|
} |
5348
|
|
|
} |
5349
|
|
|
|
5350
|
|
|
function suite_strrpos($haystack, $needle, $offset = 0, $encoding = DEFAULT_UTIL_SUITE_ENCODING) |
5351
|
|
|
{ |
5352
|
|
|
if (function_exists('mb_strrpos')) { |
5353
|
|
|
return mb_strrpos($haystack, $needle, $offset, $encoding); |
5354
|
|
|
} else { |
5355
|
|
|
return strrpos($haystack, $needle, $offset); |
5356
|
|
|
} |
5357
|
|
|
} |
5358
|
|
|
|
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: