Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

4799 lines (4172 sloc) 152.518 kB
<?php
/*********************************************************************************
* SugarCRM Community Edition is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
/*********************************************************************************
* Description: Includes generic helper functions used throughout the application.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
********************************************************************************/
require_once('include/SugarObjects/SugarConfig.php');
require_once('include/utils/security_utils.php');
function make_sugar_config(&$sugar_config)
{
/* used to convert non-array config.php file to array format */
global $admin_export_only;
global $cache_dir;
global $calculate_response_time;
global $create_default_user;
global $dateFormats;
global $dbconfig;
global $dbconfigoption;
global $default_action;
global $default_charset;
global $default_currency_name;
global $default_currency_symbol;
global $default_currency_iso4217;
global $defaultDateFormat;
global $default_language;
global $default_module;
global $default_password;
global $default_permission_mode;
global $default_theme;
global $defaultTimeFormat;
global $default_user_is_admin;
global $default_user_name;
global $disable_export;
global $disable_persistent_connections;
global $display_email_template_variable_chooser;
global $display_inbound_email_buttons;
global $history_max_viewed;
global $host_name;
global $import_dir;
global $languages;
global $list_max_entries_per_page;
global $lock_default_user_name;
global $log_memory_usage;
global $nameFormats;
global $requireAccounts;
global $RSS_CACHE_TIME;
global $session_dir;
global $site_URL;
global $site_url;
global $sugar_version;
global $timeFormats;
global $tmp_dir;
global $translation_string_prefix;
global $unique_key;
global $upload_badext;
global $upload_dir;
global $upload_maxsize;
global $import_max_execution_time;
global $list_max_entries_per_subpanel;
global $passwordsetting;
// assumes the following variables must be set:
// $dbconfig, $dbconfigoption, $cache_dir, $session_dir, $site_URL, $upload_dir
$sugar_config = array (
'admin_export_only' => empty($admin_export_only) ? false : $admin_export_only,
'export_delimiter' => empty($export_delimiter) ? ',' : $export_delimiter,
'cache_dir' => empty($cache_dir) ? 'cache/' : $cache_dir,
'calculate_response_time' => empty($calculate_response_time) ? true : $calculate_response_time,
'create_default_user' => empty($create_default_user) ? false : $create_default_user,
'chartEngine' => 'Jit',
'date_formats' => empty($dateFormats) ? array(
'Y-m-d'=>'2010-12-23',
'd-m-Y' => '23-12-2010',
'm-d-Y'=>'12-23-2010',
'Y/m/d'=>'2010/12/23',
'd/m/Y' => '23/12/2010',
'm/d/Y'=>'12/23/2010',
'Y.m.d' => '2010.12.23',
'd.m.Y' => '23.12.2010',
'm.d.Y' => '12.23.2010'
) : $dateFormats,
'dbconfig' => $dbconfig, // this must be set!!
'dbconfigoption' => $dbconfigoption, // this must be set!!
'default_action' => empty($default_action) ? 'index' : $default_action,
'default_charset' => empty($default_charset) ? 'UTF-8' : $default_charset,
'default_currency_name' => empty($default_currency_name) ? 'US Dollar' : $default_currency_name,
'default_currency_symbol' => empty($default_currency_symbol) ? '$' : $default_currency_symbol,
'default_currency_iso4217' => empty($default_currency_iso4217) ? '$' : $default_currency_iso4217,
'default_date_format' => empty($defaultDateFormat) ? 'm/d/Y' : $defaultDateFormat,
'default_locale_name_format' => empty($defaultNameFormat) ? 's f l' : $defaultNameFormat,
'default_export_charset' => 'UTF-8',
'default_language' => empty($default_language) ? 'en_us' : $default_language,
'default_module' => empty($default_module) ? 'Home' : $default_module,
'default_password' => empty($default_password) ? '' : $default_password,
'default_permissions' => array (
'dir_mode' => 02770,
'file_mode' => 0660,
'chown' => '',
'chgrp' => '',
),
'default_theme' => empty($default_theme) ? 'Sugar5' : $default_theme,
'default_time_format' => empty($defaultTimeFormat) ? 'h:ia' : $defaultTimeFormat,
'default_user_is_admin' => empty($default_user_is_admin) ? false : $default_user_is_admin,
'default_user_name' => empty($default_user_name) ? '' : $default_user_name,
'disable_export' => empty($disable_export) ? false : $disable_export,
'disable_persistent_connections' => empty($disable_persistent_connections) ? false : $disable_persistent_connections,
'display_email_template_variable_chooser' => empty($display_email_template_variable_chooser) ? false : $display_email_template_variable_chooser,
'display_inbound_email_buttons' => empty($display_inbound_email_buttons) ? false : $display_inbound_email_buttons,
'history_max_viewed' => empty($history_max_viewed) ? 50 : $history_max_viewed,
'host_name' => empty($host_name) ? 'localhost' : $host_name,
'import_dir' => $import_dir, // this must be set!!
'import_max_records_per_file' => 100,
'import_max_records_total_limit' => '',
'languages' => empty($languages) ? array('en_us' => 'English (US)') : $languages,
'list_max_entries_per_page' => empty($list_max_entries_per_page) ? 20 : $list_max_entries_per_page,
'list_max_entries_per_subpanel' => empty($list_max_entries_per_subpanel) ? 10 : $list_max_entries_per_subpanel,
'lock_default_user_name' => empty($lock_default_user_name) ? false : $lock_default_user_name,
'log_memory_usage' => empty($log_memory_usage) ? false : $log_memory_usage,
'name_formats' => empty($nameFormats) ? array(
's f l' => 's f l', 'f l' => 'f l', 's l' => 's l', 'l, s f' => 'l, s f',
'l, f' => 'l, f', 's l, f' => 's l, f', 'l s f' => 'l s f', 'l f s' => 'l f s'
) : $nameFormats,
'portal_view' => 'single_user',
'resource_management' => array (
'special_query_limit' => 50000,
'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'),
'default_limit' => 1000,
),
'require_accounts' => empty($requireAccounts) ? true : $requireAccounts,
'rss_cache_time' => empty($RSS_CACHE_TIME) ? '10800' : $RSS_CACHE_TIME,
'session_dir' => $session_dir, // this must be set!!
'site_url' => empty($site_URL) ? $site_url : $site_URL, // this must be set!!
'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable
'showThemePicker' => true,
'sugar_version' => empty($sugar_version) ? 'unknown' : $sugar_version,
'time_formats' => empty($timeFormats) ? array (
'H:i'=>'23:00', 'h:ia'=>'11:00 pm', 'h:iA'=>'11:00PM',
'H.i'=>'23.00', 'h.ia'=>'11.00 pm', 'h.iA'=>'11.00PM' ) : $timeFormats,
'tmp_dir' => $tmp_dir, // this must be set!!
'translation_string_prefix' => empty($translation_string_prefix) ? false : $translation_string_prefix,
'unique_key' => empty($unique_key) ? md5(create_guid()) : $unique_key,
'upload_badext' => empty($upload_badext) ? array (
'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py',
'asp', 'cfm', 'js', 'vbs', 'html', 'htm' ) : $upload_badext,
'upload_dir' => $upload_dir, // this must be set!!
'upload_maxsize' => empty($upload_maxsize) ? 30000000 : $upload_maxsize,
'import_max_execution_time' => empty($import_max_execution_time) ? 3600 : $import_max_execution_time,
'lock_homepage' => false,
'lock_subpanels' => false,
'max_dashlets_homepage' => 15,
'dashlet_display_row_options' => array('1','3','5','10'),
'default_max_tabs' => empty($max_tabs) ? '7' : $max_tabs,
'default_subpanel_tabs' => empty($subpanel_tabs) ? true : $subpanel_tabs,
'default_subpanel_links' => empty($subpanel_links) ? false : $subpanel_links,
'default_swap_last_viewed' => empty($swap_last_viewed) ? false : $swap_last_viewed,
'default_swap_shortcuts' => empty($swap_shortcuts) ? false : $swap_shortcuts,
'default_navigation_paradigm' => empty($navigation_paradigm) ? 'gm' : $navigation_paradigm,
'default_call_status' => 'Planned',
'js_lang_version' => 1,
'passwordsetting' => empty($passwordsetting) ? array (
'SystemGeneratedPasswordON' => '',
'generatepasswordtmpl' => '',
'lostpasswordtmpl' => '',
'forgotpasswordON' => true,
'linkexpiration' => '1',
'linkexpirationtime' => '30',
'linkexpirationtype' => '1',
'systexpiration' => '0',
'systexpirationtime' => '',
'systexpirationtype' => '0',
'systexpirationlogin' => '',
) : $passwordsetting,
'use_sprites' => function_exists('imagecreatetruecolor'),
'search_wildcard_infront' => false,
'search_wildcard_char' => '%',
'jobs' => array(
'min_retry_interval' => 60, // minimal job retry delay
'max_retries' => 5, // how many times to retry the job
'timeout' => 86400, // how long a job may spend as running before being force-failed
),
"cron" => array(
'max_cron_jobs' => 10, // max jobs per cron schedule run
'max_cron_runtime' => 60, // max runtime for cron jobs
'min_cron_interval' => 30, // minimal interval between cron jobs
),
);
}
function get_sugar_config_defaults() {
global $locale;
/**
* used for getting base values for array style config.php. used by the
* installer and to fill in new entries on upgrades. see also:
* sugar_config_union
*/
$sugar_config_defaults = array (
'admin_export_only' => false,
'export_delimiter' => ',',
'cache_dir' => 'cache/',
'calculate_response_time' => true,
'create_default_user' => false,
'chartEngine' => 'Jit',
'date_formats' => array (
'Y-m-d' => '2010-12-23', 'm-d-Y' => '12-23-2010', 'd-m-Y' => '23-12-2010',
'Y/m/d' => '2010/12/23', 'm/d/Y' => '12/23/2010', 'd/m/Y' => '23/12/2010',
'Y.m.d' => '2010.12.23', 'd.m.Y' => '23.12.2010', 'm.d.Y' => '12.23.2010',),
'name_formats' => array (
's f l' => 's f l', 'f l' => 'f l', 's l' => 's l', 'l, s f' => 'l, s f',
'l, f' => 'l, f', 's l, f' => 's l, f', 'l s f' => 'l s f', 'l f s' => 'l f s'
),
'dbconfigoption' => array (
'persistent' => true,
'autofree' => false,
'debug' => 0,
'ssl' => false ),
'default_action' => 'index',
'default_charset' => return_session_value_or_default('default_charset',
'UTF-8'),
'default_currency_name' => return_session_value_or_default('default_currency_name', 'US Dollar'),
'default_currency_symbol' => return_session_value_or_default('default_currency_symbol', '$'),
'default_currency_iso4217' => return_session_value_or_default('default_currency_iso4217', 'USD'),
'default_currency_significant_digits' => return_session_value_or_default('default_currency_significant_digits', 2),
'default_number_grouping_seperator' => return_session_value_or_default('default_number_grouping_seperator', ','),
'default_decimal_seperator' => return_session_value_or_default('default_decimal_seperator', '.'),
'default_date_format' => 'm/d/Y',
'default_locale_name_format' => 's f l',
'default_export_charset' => 'UTF-8',
'default_language' => return_session_value_or_default('default_language',
'en_us'),
'default_module' => 'Home',
'default_password' => '',
'default_permissions' => array (
'dir_mode' => 02770,
'file_mode' => 0660,
'user' => '',
'group' => '',
),
'default_theme' => return_session_value_or_default('site_default_theme', 'Sugar5'),
'default_time_format' => 'h:ia',
'default_user_is_admin' => false,
'default_user_name' => '',
'disable_export' => false,
'disable_persistent_connections' =>
return_session_value_or_default('disable_persistent_connections',
'false'),
'display_email_template_variable_chooser' => false,
'display_inbound_email_buttons' => false,
'dump_slow_queries' => false,
'email_address_separator' => ',', // use RFC2368 spec unless we have a noncompliant email client
'email_default_editor' => 'html',
'email_default_client' => 'sugar',
'email_default_delete_attachments' => true,
'history_max_viewed' => 50,
'installer_locked' => true,
'import_max_records_per_file' => 100,
'import_max_records_total_limit' => '',
'languages' => array('en_us' => 'English (US)'),
'large_scale_test' => false,
'list_max_entries_per_page' => 20,
'list_max_entries_per_subpanel' => 10,
'lock_default_user_name' => false,
'log_memory_usage' => false,
'portal_view' => 'single_user',
'resource_management' => array (
'special_query_limit' => 50000,
'special_query_modules' => array('Reports', 'Export', 'Import', 'Administration', 'Sync'),
'default_limit' => 1000,
),
'require_accounts' => true,
'rss_cache_time' => return_session_value_or_default('rss_cache_time',
'10800'),
'save_query' => 'all',
'showDetailData' => true, // if true, read-only ACL fields will still appear on EditViews as non-editable
'showThemePicker' => true,
'slow_query_time_msec' => '100',
'sugarbeet' => true,
'time_formats' => array (
'H:i'=>'23:00', 'h:ia'=>'11:00pm', 'h:iA'=>'11:00PM', 'h:i a'=>'11:00 pm', 'h:i A'=>'11:00 PM',
'H.i'=>'23.00', 'h.ia'=>'11.00pm', 'h.iA'=>'11.00PM', 'h.i a'=>'11.00 pm', 'h.i A'=>'11.00 PM' ),
'tracker_max_display_length' => 15,
'translation_string_prefix' =>
return_session_value_or_default('translation_string_prefix', false),
'upload_badext' => array (
'php', 'php3', 'php4', 'php5', 'pl', 'cgi', 'py',
'asp', 'cfm', 'js', 'vbs', 'html', 'htm' ),
'upload_maxsize' => 30000000,
'import_max_execution_time' => 3600,
// 'use_php_code_json' => returnPhpJsonStatus(),
'verify_client_ip' => true,
'js_custom_version' => '',
'js_lang_version' => 1,
'lead_conv_activity_opt' => 'donothing',
'default_number_grouping_seperator' => ',',
'default_decimal_seperator' => '.',
'lock_homepage' => false,
'lock_subpanels' => false,
'max_dashlets_homepage' => '15',
'default_max_tabs' => '7',
'dashlet_display_row_options' => array('1','3','5','10'),
'default_subpanel_tabs' => true,
'default_subpanel_links' => false,
'default_swap_last_viewed' => false,
'default_swap_shortcuts' => false,
'default_navigation_paradigm' => 'gm',
'admin_access_control' => false,
'use_common_ml_dir' => false,
'common_ml_dir' => '',
'vcal_time' => '2',
'calendar' => array(
'default_view' => 'week',
'show_calls_by_default' => true,
'show_tasks_by_default' => true,
'editview_width' => 990,
'editview_height' => 485,
'day_timestep' => 15,
'week_timestep' => 30,
'items_draggable' => true,
'items_resizable' => true,
'enable_repeat' => true,
'max_repeat_count' => 1000,
),
'passwordsetting' => empty($passwordsetting) ? array (
'SystemGeneratedPasswordON' => '',
'generatepasswordtmpl' => '',
'lostpasswordtmpl' => '',
'forgotpasswordON' => false,
'linkexpiration' => '1',
'linkexpirationtime' => '30',
'linkexpirationtype' => '1',
'systexpiration' => '0',
'systexpirationtime' => '',
'systexpirationtype' => '0',
'systexpirationlogin' => '',
) : $passwordsetting,
'use_real_names' => true,
'search_wildcard_infront' => false,
'search_wildcard_char' => '%',
'jobs' => array(
'min_retry_interval' => 30, // 30 seconds minimal job retry
'max_retries' => 5, // how many times to retry the job
'timeout' => 86400, // how long a job may spend as running before being force-failed
),
"cron" => array(
'max_cron_jobs' => 10, // max jobs per cron schedule run
'max_cron_runtime' => 30, // max runtime for cron jobs
'min_cron_interval' => 30, // minimal interval between cron jobs
),
);
if(!is_object($locale)) {
$locale = new Localization();
}
$sugar_config_defaults['default_currencies'] = $locale->getDefaultCurrencies();
$sugar_config_defaults = sugarArrayMerge($locale->getLocaleConfigDefaults(), $sugar_config_defaults);
return( $sugar_config_defaults );
}
/**
* @deprecated use SugarView::getMenu() instead
*/
function load_menu($path){
global $module_menu;
if(file_exists($path . 'Menu.php'))
{
require($path . 'Menu.php');
}
if(file_exists('custom/' . $path . 'Ext/Menus/menu.ext.php'))
{
require('custom/' . $path . 'Ext/Menus/menu.ext.php');
}
if(file_exists('custom/application/Ext/Menus/menu.ext.php'))
{
require('custom/application/Ext/Menus/menu.ext.php');
}
return $module_menu;
}
/**
* get_notify_template_file
* This function will return the location of the email notifications template to use
*
* @return string relative file path to email notifications template file
*/
function get_notify_template_file($language){
/*
* Order of operation:
* 1) custom version of specified language
* 2) stock version of specified language
* 3) custom version of en_us template
* 4) stock en_us template
*/
// set $file to the base code template so it's set if none of the conditions pass
$file = "include/language/en_us.notify_template.html";
if(file_exists("custom/include/language/{$language}.notify_template.html")){
$file = "custom/include/language/{$language}.notify_template.html";
}
else if(file_exists("include/language/{$language}.notify_template.html")){
$file = "include/language/{$language}.notify_template.html";
}
else if(file_exists("custom/include/language/en_us.notify_template.html")){
$file = "custom/include/language/en_us.notify_template.html";
}
return $file;
}
function sugar_config_union( $default, $override ){
// a little different then array_merge and array_merge_recursive. we want
// the second array to override the first array if the same value exists,
// otherwise merge the unique keys. it handles arrays of arrays recursively
// might be suitable for a generic array_union
if( !is_array( $override ) ){
$override = array();
}
foreach( $default as $key => $value ){
if( !array_key_exists($key, $override) ){
$override[$key] = $value;
}
else if( is_array( $key ) ){
$override[$key] = sugar_config_union( $value, $override[$key] );
}
}
return( $override );
}
function make_not_writable( $file ){
// Returns true if the given file/dir has been made not writable
$ret_val = false;
if( is_file($file) || is_dir($file) ){
if( !is_writable($file) ){
$ret_val = true;
}
else {
$original_fileperms = fileperms($file);
// take away writable permissions
$new_fileperms = $original_fileperms & ~0x0092;
@sugar_chmod($file, $new_fileperms);
if( !is_writable($file) ){
$ret_val = true;
}
}
}
return $ret_val;
}
/** This function returns the name of the person.
* It currently returns "first last". It should not put the space if either name is not available.
* It should not return errors if either name is not available.
* If no names are present, it will return ""
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function return_name($row, $first_column, $last_column)
{
$first_name = "";
$last_name = "";
$full_name = "";
if(isset($row[$first_column]))
{
$first_name = stripslashes($row[$first_column]);
}
if(isset($row[$last_column]))
{
$last_name = stripslashes($row[$last_column]);
}
$full_name = $first_name;
// If we have a first name and we have a last name
if($full_name != "" && $last_name != "")
{
// append a space, then the last name
$full_name .= " ".$last_name;
}
// If we have no first name, but we have a last name
else if($last_name != "")
{
// append the last name without the space.
$full_name .= $last_name;
}
return $full_name;
}
function get_languages()
{
global $sugar_config;
$lang = $sugar_config['languages'];
if(!empty($sugar_config['disabled_languages'])){
foreach(explode(',', $sugar_config['disabled_languages']) as $disable) {
unset($lang[$disable]);
}
}
return $lang;
}
function get_all_languages()
{
global $sugar_config;
return $sugar_config['languages'];
}
function get_language_display($key)
{
global $sugar_config;
return $sugar_config['languages'][$key];
}
function get_assigned_user_name($assigned_user_id, $is_group = '') {
static $saved_user_list = null;
if(empty($saved_user_list)) {
$saved_user_list = get_user_array(false, '', '', false, null, $is_group);
}
if(isset($saved_user_list[$assigned_user_id])) {
return $saved_user_list[$assigned_user_id];
}
return '';
}
/**
* retrieves the user_name column value (login)
* @param string id GUID of user
* @return string
*/
function get_user_name($id) {
global $db;
if(empty($db))
$db = DBManagerFactory::getInstance();
$q = "SELECT user_name FROM users WHERE id='{$id}'";
$r = $db->query($q);
$a = $db->fetchByAssoc($r);
return (empty($a)) ? '' : $a['user_name'];
}
//TODO Update to use global cache
/**
* get_user_array
*
* This is a helper function to return an Array of users depending on the parameters passed into the function.
* This function uses the get_register_value function by default to use a caching layer where supported.
*
* @param bool $add_blank Boolean value to add a blank entry to the array results, true by default
* @param string $status String value indicating the status to filter users by, "Active" by default
* @param string $user_id String value to specify a particular user id value (searches the id column of users table), blank by default
* @param bool $use_real_name Boolean value indicating whether or not results should include the full name or just user_name, false by default
* @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
* @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
* @param bool $from_cache Boolean value indicating whether or not to use the get_register_value function for caching, true by default
* @return array Array of users matching the filter criteria that may be from cache (if similar search was previously run)
*/
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) {
global $locale;
global $sugar_config;
if(empty($locale)) {
$locale = new Localization();
}
if($from_cache) {
$key_name = $add_blank. $status . $user_id . $use_real_name . $user_name_filter . $portal_filter;
$user_array = get_register_value('user_array', $key_name);
}
if(empty($user_array)) {
$db = DBManagerFactory::getInstance();
$temp_result = Array();
// Including deleted users for now.
if (empty($status)) {
$query = "SELECT id, first_name, last_name, user_name from users WHERE 1=1".$portal_filter;
}
else {
$query = "SELECT id, first_name, last_name, user_name from users WHERE status='$status'".$portal_filter;
}
if (!empty($user_name_filter)) {
$user_name_filter = $db->quote($user_name_filter);
$query .= " AND user_name LIKE '$user_name_filter%' ";
}
if (!empty($user_id)) {
$query .= " OR id='{$user_id}'";
}
$query = $query.' ORDER BY user_name ASC';
$GLOBALS['log']->debug("get_user_array query: $query");
$result = $db->query($query, true, "Error filling in user array: ");
if ($add_blank==true) {
// Add in a blank row
$temp_result[''] = '';
}
// Get the id and the name.
while($row = $db->fetchByAssoc($result)) {
if($use_real_name == true || showFullName()) {
if(isset($row['last_name'])) { // cn: we will ALWAYS have both first_name and last_name (empty value if blank in db)
$temp_result[$row['id']] = $locale->getLocaleFormattedName($row['first_name'],$row['last_name']);
} else {
$temp_result[$row['id']] = $row['user_name'];
}
} else {
$temp_result[$row['id']] = $row['user_name'];
}
}
$user_array = $temp_result;
if($from_cache)
{
set_register_value('user_array', $key_name, $temp_result);
}
}
return $user_array;
}
/**
* uses a different query to return a list of users than get_user_array()
* Used from QuickSearch.php
* @param args string where clause entry
* @return array Array of Users' details that match passed criteria
*/
function getUserArrayFromFullName($args, $hide_portal_users = false) {
global $locale;
$db = DBManagerFactory::getInstance();
// jmorais@dri - Bug #51411
//
// Refactor the code responsible for parsing supplied $args, this way we
// ensure that if $args has at least one space (after trim), the $inClause
// will be composed by several clauses ($inClauses) inside parenthesis.
//
// Ensuring that operator precedence is respected, and avoiding
// inactive/deleted users to be retrieved.
//
$args = trim($args);
if (strpos($args, ' ')) {
$inClauses = array();
$argArray = explode(' ', $args);
foreach ($argArray as $arg) {
$arg = $db->quote($arg);
$inClauses[] = "(first_name LIKE '{$arg}%' OR last_name LIKE '{$arg}%')";
}
$inClause = '(' . implode('OR ', $inClauses) . ')';
} else {
$args = $db->quote($args);
$inClause = "(first_name LIKE '{$args}%' OR last_name LIKE '{$args}%')";
}
// ~jmorais@dri
$query = "SELECT id, first_name, last_name, user_name FROM users WHERE status='Active' AND deleted=0 AND ";
if ( $hide_portal_users ) {
$query .= " portal_only=0 AND ";
}
$query .= $inClause;
$query .= " ORDER BY last_name ASC";
$r = $db->query($query);
$ret = array();
while($a = $db->fetchByAssoc($r)) {
$ret[$a['id']] = $locale->getLocaleFormattedName($a['first_name'], $a['last_name']);
}
return $ret;
}
/**
*
* based on user pref then system pref
*/
function showFullName() {
global $sugar_config;
global $current_user;
static $showFullName = null;
if (is_null($showFullName)) {
$sysPref = !empty($sugar_config['use_real_names']);
$userPref = (is_object($current_user)) ? $current_user->getPreference('use_real_names') : null;
if($userPref != null) {
$showFullName = ($userPref == 'on');
} else {
$showFullName = $sysPref;
}
}
return $showFullName;
}
function clean($string, $maxLength)
{
$string = substr($string, 0, $maxLength);
return escapeshellcmd($string);
}
/**
* Copy the specified request variable to the member variable of the specified object.
* Do no copy if the member variable is already set.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function safe_map($request_var, & $focus, $always_copy = false)
{
safe_map_named($request_var, $focus, $request_var, $always_copy);
}
/**
* Copy the specified request variable to the member variable of the specified object.
* Do no copy if the member variable is already set.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function safe_map_named($request_var, & $focus, $member_var, $always_copy)
{
if (isset($_REQUEST[$request_var]) && ($always_copy || is_null($focus->$member_var))) {
$GLOBALS['log']->debug("safe map named called assigning '{$_REQUEST[$request_var]}' to $member_var");
$focus->$member_var = $_REQUEST[$request_var];
}
}
/**
* This function retrieves an application language file and returns the array of strings included in the $app_list_strings var.
*
* @param string $language specific language to load
* @return array lang strings
*/
function return_app_list_strings_language($language)
{
global $app_list_strings;
global $sugar_config;
$cache_key = 'app_list_strings.'.$language;
// Check for cached value
$cache_entry = sugar_cache_retrieve($cache_key);
if(!empty($cache_entry))
{
return $cache_entry;
}
$default_language = $sugar_config['default_language'];
$temp_app_list_strings = $app_list_strings;
$langs = array();
if ($language != 'en_us') {
$langs[] = 'en_us';
}
if ($default_language != 'en_us' && $language != $default_language) {
$langs[] = $default_language;
}
$langs[] = $language;
$app_list_strings_array = array();
foreach ( $langs as $lang ) {
$app_list_strings = array();
if(file_exists("include/language/$lang.lang.php")) {
include("include/language/$lang.lang.php");
$GLOBALS['log']->info("Found language file: $lang.lang.php");
}
if(file_exists("include/language/$lang.lang.override.php")) {
include("include/language/$lang.lang.override.php");
$GLOBALS['log']->info("Found override language file: $lang.lang.override.php");
}
if(file_exists("include/language/$lang.lang.php.override")) {
include("include/language/$lang.lang.php.override");
$GLOBALS['log']->info("Found override language file: $lang.lang.php.override");
}
$app_list_strings_array[] = $app_list_strings;
}
$app_list_strings = array();
foreach ( $app_list_strings_array as $app_list_strings_item ) {
$app_list_strings = sugarLangArrayMerge($app_list_strings, $app_list_strings_item);
}
foreach ( $langs as $lang ) {
if(file_exists("custom/application/Ext/Language/$lang.lang.ext.php")) {
$app_list_strings = _mergeCustomAppListStrings("custom/application/Ext/Language/$lang.lang.ext.php" , $app_list_strings);
$GLOBALS['log']->info("Found extended language file: $lang.lang.ext.php");
}
if(file_exists("custom/include/language/$lang.lang.php")) {
include("custom/include/language/$lang.lang.php");
$GLOBALS['log']->info("Found custom language file: $lang.lang.php");
}
}
if(!isset($app_list_strings)) {
$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");
return null;
}
$return_value = $app_list_strings;
$app_list_strings = $temp_app_list_strings;
sugar_cache_put($cache_key, $return_value);
return $return_value;
}
/**
* The dropdown items in custom language files is $app_list_strings['$key']['$second_key'] = $value not
* $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.
* @param file string the language that you want include,
* @param app_list_strings array the golbal strings
* @return array
*/
//jchi 25347
function _mergeCustomAppListStrings($file , $app_list_strings){
$app_list_strings_original = $app_list_strings;
unset($app_list_strings);
// FG - bug 45525 - $exemptDropdown array is defined (once) here, not inside the foreach
// This way, language file can add items to save specific standard codelist from being overwritten
$exemptDropdowns = array();
include($file);
if(!isset($app_list_strings) || !is_array($app_list_strings)){
return $app_list_strings_original;
}
//Bug 25347: We should not merge custom dropdown fields unless they relate to parent fields or the module list.
// FG - bug 45525 - Specific codelists must NOT be overwritten
$exemptDropdowns[] = "moduleList";
$exemptDropdowns[] = "parent_type_display";
$exemptDropdowns[] = "record_type_display";
$exemptDropdowns[] = "record_type_display_notes";
foreach($app_list_strings as $key=>$value)
{
if (!in_array($key, $exemptDropdowns) && array_key_exists($key, $app_list_strings_original))
{
unset($app_list_strings_original["$key"]);
}
}
$app_list_strings = sugarArrayMergeRecursive($app_list_strings_original , $app_list_strings);
return $app_list_strings;
}
/**
* This function retrieves an application language file and returns the array of strings included.
*
* @param string $language specific language to load
* @return array lang strings
*/
function return_application_language($language)
{
global $app_strings, $sugar_config;
$cache_key = 'app_strings.'.$language;
// Check for cached value
$cache_entry = sugar_cache_retrieve($cache_key);
if(!empty($cache_entry))
{
return $cache_entry;
}
$temp_app_strings = $app_strings;
$default_language = $sugar_config['default_language'];
$langs = array();
if ($language != 'en_us') {
$langs[] = 'en_us';
}
if ($default_language != 'en_us' && $language != $default_language) {
$langs[] = $default_language;
}
$langs[] = $language;
$app_strings_array = array();
foreach ( $langs as $lang ) {
$app_strings = array();
if(file_exists("include/language/$lang.lang.php")) {
include("include/language/$lang.lang.php");
$GLOBALS['log']->info("Found language file: $lang.lang.php");
}
if(file_exists("include/language/$lang.lang.override.php")) {
include("include/language/$lang.lang.override.php");
$GLOBALS['log']->info("Found override language file: $lang.lang.override.php");
}
if(file_exists("include/language/$lang.lang.php.override")) {
include("include/language/$lang.lang.php.override");
$GLOBALS['log']->info("Found override language file: $lang.lang.php.override");
}
if(file_exists("custom/application/Ext/Language/$lang.lang.ext.php")) {
include("custom/application/Ext/Language/$lang.lang.ext.php");
$GLOBALS['log']->info("Found extended language file: $lang.lang.ext.php");
}
if(file_exists("custom/include/language/$lang.lang.php")) {
include("custom/include/language/$lang.lang.php");
$GLOBALS['log']->info("Found custom language file: $lang.lang.php");
}
$app_strings_array[] = $app_strings;
}
$app_strings = array();
foreach ( $app_strings_array as $app_strings_item ) {
$app_strings = sugarLangArrayMerge($app_strings, $app_strings_item);
}
if(!isset($app_strings)) {
$GLOBALS['log']->fatal("Unable to load the application language strings");
return null;
}
// If we are in debug mode for translating, turn on the prefix now!
if($sugar_config['translation_string_prefix']) {
foreach($app_strings as $entry_key=>$entry_value) {
$app_strings[$entry_key] = $language.' '.$entry_value;
}
}
if(isset($_SESSION['show_deleted'])) {
$app_strings['LBL_DELETE_BUTTON'] = $app_strings['LBL_UNDELETE_BUTTON'];
$app_strings['LBL_DELETE_BUTTON_LABEL'] = $app_strings['LBL_UNDELETE_BUTTON_LABEL'];
$app_strings['LBL_DELETE_BUTTON_TITLE'] = $app_strings['LBL_UNDELETE_BUTTON_TITLE'];
$app_strings['LBL_DELETE'] = $app_strings['LBL_UNDELETE'];
}
$app_strings['LBL_ALT_HOT_KEY'] = get_alt_hot_key();
$return_value = $app_strings;
$app_strings = $temp_app_strings;
sugar_cache_put($cache_key, $return_value);
return $return_value;
}
/**
* This function retrieves a module's language file and returns the array of strings included.
*
* @param string $language specific language to load
* @param string $module module name to load strings for
* @param bool $refresh optional, true if you want to rebuild the language strings
* @return array lang strings
*/
function return_module_language($language, $module, $refresh=false)
{
global $mod_strings;
global $sugar_config;
global $currentModule;
// Jenny - Bug 8119: Need to check if $module is not empty
if (empty($module)) {
$stack = debug_backtrace();
$GLOBALS['log']->warn("Variable module is not in return_module_language ". var_export($stack, true));
return array();
}
if( !$refresh )
{
$cache_key = LanguageManager::getLanguageCacheKey($module, $language);
// Check for cached value
$cache_entry = sugar_cache_retrieve($cache_key);
if(!empty($cache_entry) && is_array($cache_entry))
{
return $cache_entry;
}
}
// Store the current mod strings for later
$temp_mod_strings = $mod_strings;
$loaded_mod_strings = array();
$language_used = $language;
$default_language = $sugar_config['default_language'];
if(empty($language)) {
$language = $default_language;
}
// Bug 21559 - So we can get all the strings defined in the template, refresh
// the vardefs file if the cached language file doesn't exist.
if(!file_exists(sugar_cached('modules/'). $module . '/language/'.$language.'.lang.php')
&& !empty($GLOBALS['beanList'][$module])){
$object = BeanFactory::getObjectName($module);
VardefManager::refreshVardefs($module,$object);
}
$loaded_mod_strings = LanguageManager::loadModuleLanguage($module, $language,$refresh);
// cn: bug 6048 - merge en_us with requested language
if($language != $sugar_config['default_language'])
$loaded_mod_strings = sugarLangArrayMerge(
LanguageManager::loadModuleLanguage($module, $sugar_config['default_language'],$refresh),
$loaded_mod_strings
);
// Load in en_us strings by default
if($language != 'en_us' && $sugar_config['default_language'] != 'en_us')
$loaded_mod_strings = sugarLangArrayMerge(
LanguageManager::loadModuleLanguage($module, 'en_us', $refresh),
$loaded_mod_strings
);
// If we are in debug mode for translating, turn on the prefix now!
if($sugar_config['translation_string_prefix']) {
foreach($loaded_mod_strings as $entry_key=>$entry_value) {
$loaded_mod_strings[$entry_key] = $language_used.' '.$entry_value;
}
}
$return_value = $loaded_mod_strings;
if(!isset($mod_strings)){
$mod_strings = $return_value;
}
else
$mod_strings = $temp_mod_strings;
$cache_key = LanguageManager::getLanguageCacheKey($module, $language);
sugar_cache_put($cache_key, $return_value);
return $return_value;
}
/** This function retrieves an application language file and returns the array of strings included in the $mod_list_strings var.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
* If you are using the current language, do not call this function unless you are loading it for the first time */
function return_mod_list_strings_language($language,$module) {
global $mod_list_strings;
global $sugar_config;
global $currentModule;
$cache_key = "mod_list_str_lang.".$language.$module;
// Check for cached value
$cache_entry = sugar_cache_retrieve($cache_key);
if(!empty($cache_entry))
{
return $cache_entry;
}
$language_used = $language;
$temp_mod_list_strings = $mod_list_strings;
$default_language = $sugar_config['default_language'];
if($currentModule == $module && isset($mod_list_strings) && $mod_list_strings != null) {
return $mod_list_strings;
}
// cn: bug 6351 - include en_us if file langpack not available
// cn: bug 6048 - merge en_us with requested language
include("modules/$module/language/en_us.lang.php");
$en_mod_list_strings = array();
if($language_used != $default_language)
$en_mod_list_strings = $mod_list_strings;
if(file_exists("modules/$module/language/$language.lang.php")) {
include("modules/$module/language/$language.lang.php");
}
if(file_exists("modules/$module/language/$language.lang.override.php")){
include("modules/$module/language/$language.lang.override.php");
}
if(file_exists("modules/$module/language/$language.lang.php.override")){
echo 'Please Change:<br>' . "modules/$module/language/$language.lang.php.override" . '<br>to<br>' . 'Please Change:<br>' . "modules/$module/language/$language.lang.override.php";
include("modules/$module/language/$language.lang.php.override");
}
// cn: bug 6048 - merge en_us with requested language
$mod_list_strings = sugarLangArrayMerge($en_mod_list_strings, $mod_list_strings);
// if we still don't have a language pack, then log an error
if(!isset($mod_list_strings)) {
$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})");
return null;
}
$return_value = $mod_list_strings;
$mod_list_strings = $temp_mod_list_strings;
sugar_cache_put($cache_key, $return_value);
return $return_value;
}
/** This function retrieves a theme's language file and returns the array of strings included.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function return_theme_language($language, $theme)
{
global $mod_strings, $sugar_config, $current_language;
$language_used = $language;
$default_language = $sugar_config['default_language'];
include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php");
if(file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php")){
include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.override.php");
}
if(file_exists(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override")){
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";
include(SugarThemeRegistry::get($theme)->getFilePath()."/language/$current_language.lang.php.override");
}
if(!isset($theme_strings))
{
$GLOBALS['log']->warn("Unable to find the theme file for language: ".$language." and theme: ".$theme);
require(SugarThemeRegistry::get($theme)->getFilePath()."/language/$default_language.lang.php");
$language_used = $default_language;
}
if(!isset($theme_strings))
{
$GLOBALS['log']->fatal("Unable to load the theme($theme) language file for the selected language($language) or the default language($default_language)");
return null;
}
// If we are in debug mode for translating, turn on the prefix now!
if($sugar_config['translation_string_prefix'])
{
foreach($theme_strings as $entry_key=>$entry_value)
{
$theme_strings[$entry_key] = $language_used.' '.$entry_value;
}
}
return $theme_strings;
}
/** If the session variable is defined and is not equal to "" then return it. Otherwise, return the default value.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function return_session_value_or_default($varname, $default)
{
if(isset($_SESSION[$varname]) && $_SESSION[$varname] != "")
{
return $_SESSION[$varname];
}
return $default;
}
/**
* Creates an array of where restrictions. These are used to construct a where SQL statement on the query
* 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.
* @param &$where_clauses - The array to append the clause to
* @param $variable_name - The name of the variable to look for an add to the where clause if found
* @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.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function append_where_clause(&$where_clauses, $variable_name, $SQL_name = null)
{
if($SQL_name == null)
{
$SQL_name = $variable_name;
}
if(isset($_REQUEST[$variable_name]) && $_REQUEST[$variable_name] != "")
{
array_push($where_clauses, "$SQL_name like '".$GLOBALS['db']->quote($_REQUEST[$variable_name])."%'");
}
}
/**
* Generate the appropriate SQL based on the where clauses.
* @param $where_clauses - An Array of individual where clauses stored as strings
* @returns string where_clause - The final SQL where clause to be executed.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function generate_where_statement($where_clauses)
{
$where = "";
foreach($where_clauses as $clause)
{
if($where != "")
$where .= " and ";
$where .= $clause;
}
$GLOBALS['log']->info("Here is the where clause for the list view: $where");
return $where;
}
/**
* determines if a passed string matches the criteria for a Sugar GUID
* @param string $guid
* @return bool False on failure
*/
function is_guid($guid) {
if(strlen($guid) != 36) {
return false;
}
if(preg_match("/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/i", $guid)) {
return true;
}
return true;;
}
/**
* A temporary method of generating GUIDs of the correct format for our DB.
* @return String contianing a GUID in the format: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
*
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function create_guid()
{
$microTime = microtime();
list($a_dec, $a_sec) = explode(" ", $microTime);
$dec_hex = dechex($a_dec* 1000000);
$sec_hex = dechex($a_sec);
ensure_length($dec_hex, 5);
ensure_length($sec_hex, 6);
$guid = "";
$guid .= $dec_hex;
$guid .= create_guid_section(3);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= $sec_hex;
$guid .= create_guid_section(6);
return $guid;
}
function create_guid_section($characters)
{
$return = "";
for($i=0; $i<$characters; $i++)
{
$return .= dechex(mt_rand(0,15));
}
return $return;
}
function ensure_length(&$string, $length)
{
$strlen = strlen($string);
if($strlen < $length)
{
$string = str_pad($string,$length,"0");
}
else if($strlen > $length)
{
$string = substr($string, 0, $length);
}
}
function microtime_diff($a, $b) {
list($a_dec, $a_sec) = explode(" ", $a);
list($b_dec, $b_sec) = explode(" ", $b);
return $b_sec - $a_sec + $b_dec - $a_dec;
}
// check if Studio is displayed.
function displayStudioForCurrentUser()
{
global $current_user;
if ( $current_user->isAdmin() ) {
return true;
}
return true;
}
function displayWorkflowForCurrentUser()
{
$_SESSION['display_workflow_for_user'] = false;
return false;
}
// return an array with all modules where the user is an admin.
function get_admin_modules_for_user($user) {
$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");
if(!isset($user)){
$modules = array();
return $modules;
}
return($user->getDeveloperModules());
}
function get_workflow_admin_modules_for_user($user){
if (isset($_SESSION['get_workflow_admin_modules_for_user'])) {
return $_SESSION['get_workflow_admin_modules_for_user'];
}
global $moduleList;
$workflow_mod_list = array();
foreach($moduleList as $module){
$workflow_mod_list[$module] = $module;
}
// This list is taken from teh previous version of workflow_utils.php
$workflow_mod_list['Tasks'] = "Tasks";
$workflow_mod_list['Calls'] = "Calls";
$workflow_mod_list['Meetings'] = "Meetings";
$workflow_mod_list['Notes'] = "Notes";
$workflow_mod_list['ProjectTask'] = "Project Tasks";
$workflow_mod_list['Leads'] = "Leads";
$workflow_mod_list['Opportunities'] = "Opportunities";
// End of list
$workflow_admin_modules = array();
if(empty($user)) {
return $workflow_admin_modules;
}
$actions = ACLAction::getUserActions($user->id);
//check for ForecastSchedule because it doesn't exist in $workflow_mod_list
if (isset($actions['ForecastSchedule']['module']['admin']['aclaccess']) && ($actions['ForecastSchedule']['module']['admin']['aclaccess']==ACL_ALLOW_DEV ||
$actions['ForecastSchedule']['module']['admin']['aclaccess']==ACL_ALLOW_ADMIN_DEV)) {
$workflow_admin_modules['Forecasts'] = 'Forecasts';
}
foreach ($workflow_mod_list as $key=>$val) {
if(!in_array($val, $workflow_admin_modules) && ($val!='iFrames' && $val!='Feeds' && $val!='Home' && $val!='Dashboard'
&& $val!='Calendar' && $val!='Activities' && $val!='Reports') &&
($user->isDeveloperForModule($key))) {
$workflow_admin_modules[$key] = $val;
}
}
$_SESSION['get_workflow_admin_modules_for_user'] = $workflow_admin_modules;
return ($workflow_admin_modules);
}
// Check if user is admin for at least one module.
function is_admin_for_any_module($user) {
if (!isset($user)){
return false;
}
if($user->isAdmin()) {
return true;
}
return false;
}
// Check if user is admin for a specific module.
function is_admin_for_module($user,$module) {
if (!isset($user)) {
return false;
}
if ($user->isAdmin()) {
return true;
}
return false;
}
/**
* Check if user id belongs to a system admin.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function is_admin($user) {
if(empty($user)) {
return false;
}
return $user->isAdmin();
}
/**
* Return the display name for a theme if it exists.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*
* @deprecated use SugarThemeRegistry::get($theme)->name instead
*/
function get_theme_display($theme)
{
return SugarThemeRegistry::get($theme)->name;
}
/**
* Return an array of directory names.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*
* @deprecated use SugarThemeRegistry::availableThemes() instead.
*/
function get_themes()
{
return SugarThemeRegistry::availableThemes();
}
/**
* THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED; USE get_select_options_with_id()
* Create HTML to display select options in a dropdown list. To be used inside
* of a select statement in a form.
* param $option_list - the array of strings to that contains the option list
* param $selected - the string which contains the default value
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function get_select_options ($option_list, $selected) {
return get_select_options_with_id($option_list, $selected);
}
/**
* Create HTML to display select options in a dropdown list. To be used inside
* 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.
* param $option_list - the array of strings to that contains the option list
* param $selected - the string which contains the default value
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function get_select_options_with_id ($option_list, $selected_key) {
return get_select_options_with_id_separate_key($option_list, $option_list, $selected_key);
}
/**
* Create HTML to display select options in a dropdown list. To be used inside
* 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.
* param $label_list - the array of strings to that contains the option list
* param $key_list - the array of strings to that contains the values list
* param $selected - the string which contains the default value
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function get_select_options_with_id_separate_key ($label_list, $key_list, $selected_key, $massupdate=false) {
global $app_strings;
$select_options = "";
//for setting null selection values to human readable --None--
$pattern = "/'0?'></";
$replacement = "''>".$app_strings['LBL_NONE']."<";
if($massupdate){
$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
}
if (empty($key_list)) $key_list = array();
//create the type dropdown domain and set the selected value if $opp value already exists
foreach ($key_list as $option_key=>$option_value) {
$selected_string = '';
// the system is evaluating $selected_key == 0 || '' to true. Be very careful when changing this. Test all cases.
// The bug was only happening with one of the users in the drop down. It was being replaced by none.
if (($option_key != '' && $selected_key == $option_key) || ($selected_key == '' && $option_key == '' && !$massupdate) || (is_array($selected_key) && in_array($option_key, $selected_key)))
{
$selected_string = 'selected ';
}
$html_value = $option_key;
$select_options .= "\n<OPTION ".$selected_string."value='$html_value'>$label_list[$option_key]</OPTION>";
}
$select_options = preg_replace($pattern, $replacement, $select_options);
return $select_options;
}
/**
* Call this method instead of die().
* Then we call the die method with the error message that is passed in.
*/
function sugar_die($error_message)
{
global $focus;
sugar_cleanup();
die($error_message);
}
/**
* Create javascript to clear values of all elements in a form.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function get_clear_form_js () {
$the_script = <<<EOQ
<script type="text/javascript" language="JavaScript">
function clear_form(form) {
var newLoc = 'index.php?action=' + form.action.value + '&module=' + form.module.value + '&query=true&clear_query=true';
if(typeof(form.advanced) != 'undefined'){
newLoc += '&advanced=' + form.advanced.value;
}
document.location.href= newLoc;
}
</script>
EOQ;
return $the_script;
}
/**
* Create javascript to set the cursor focus to specific field in a form
* when the screen is rendered. The field name is currently hardcoded into the
* the function.
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function get_set_focus_js () {
//TODO Clint 5/20 - Make this function more generic so that it can take in the target form and field names as variables
$the_script = <<<EOQ
<script type="text/javascript" language="JavaScript">
<!--
function set_focus() {
if (document.forms.length > 0) {
for (i = 0; i < document.forms.length; i++) {
for (j = 0; j < document.forms[i].elements.length; j++) {
var field = document.forms[i].elements[j];
if ((field.type == "text" || field.type == "textarea" || field.type == "password") &&
!field.disabled && (field.name == "first_name" || field.name == "name" || field.name == "user_name" || field.name=="document_name")) {
field.focus();
if (field.type == "text") {
field.select();
}
break;
}
}
}
}
}
-->
</script>
EOQ;
return $the_script;
}
/**
* Very cool algorithm for sorting multi-dimensional arrays. Found at http://us2.php.net/manual/en/function.array-multisort.php
* Syntax: $new_array = array_csort($array [, 'col1' [, SORT_FLAG [, SORT_FLAG]]]...);
* Explanation: $array is the array you want to sort, 'col1' is the name of the column
* you want to sort, SORT_FLAGS are : SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
* you can repeat the 'col',FLAG,FLAG, as often you want, the highest prioritiy is given to
* the first - so the array is sorted by the last given column first, then the one before ...
* Example: $array = array_csort($array,'town','age',SORT_DESC,'name');
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function array_csort() {
$args = func_get_args();
$marray = array_shift($args);
$i = 0;
$msortline = "return(array_multisort(";
foreach ($args as $arg) {
$i++;
if (is_string($arg)) {
foreach ($marray as $row) {
$sortarr[$i][] = $row[$arg];
}
} else {
$sortarr[$i] = $arg;
}
$msortline .= "\$sortarr[".$i."],";
}
$msortline .= "\$marray));";
eval($msortline);
return $marray;
}
/**
* Converts localized date format string to jscalendar format
* Example: $array = array_csort($array,'town','age',SORT_DESC,'name');
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
* All Rights Reserved.
* Contributor(s): ______________________________________..
*/
function parse_calendardate($local_format) {
preg_match('/\(?([^-]{1})[^-]*-([^-]{1})[^-]*-([^-]{1})[^-]*\)/', $local_format, $matches);
$calendar_format = "%" . $matches[1] . "-%" . $matches[2] . "-%" . $matches[3];
return str_replace(array("y", "ᅣ1�7", "a", "j"), array("Y", "Y", "Y", "d"), $calendar_format);
}
function translate($string, $mod='', $selectedValue=''){
//$test_start = microtime();
//static $mod_strings_results = array();
if(!empty($mod)){
global $current_language;
//Bug 31275
if(isset($_REQUEST['login_language'])){
$current_language = ($_REQUEST['login_language'] == $current_language)? $current_language : $_REQUEST['login_language'];
}
$mod_strings = return_module_language($current_language, $mod);
if ($mod == "")
echo "Language is <pre>" . $mod_strings . "</pre>";
}else{
global $mod_strings;
}
$returnValue = '';
global $app_strings, $app_list_strings;
if (isset($mod_strings[$string]))
$returnValue = $mod_strings[$string];
else if (isset($app_strings[$string]))
$returnValue = $app_strings[$string];
else if (isset($app_list_strings[$string]))
$returnValue = $app_list_strings[$string];
else if (isset($app_list_strings['moduleList']) && isset($app_list_strings['moduleList'][$string]))
$returnValue = $app_list_strings['moduleList'][$string];
//$test_end = microtime();
//
// $mod_strings_results[$mod] = microtime_diff($test_start,$test_end);
//
// echo("translate results:");
// $total_time = 0;
// $total_strings = 0;
// foreach($mod_strings_results as $key=>$value)
// {
// echo("Module $key \t\t time $value \t\t<br>");
// $total_time += $value;
// }
//
// echo("Total time: $total_time<br>");
if(empty($returnValue)){
return $string;
}
// Bug 48996 - Custom enums with '0' value were not returning because of empty check
// Added a numeric 0 checker to the conditional to allow 0 value indexed to pass
if(is_array($returnValue) && (!empty($selectedValue) || (is_numeric($selectedValue) && $selectedValue == 0)) && isset($returnValue[$selectedValue]) ){
return $returnValue[$selectedValue];
}
return $returnValue;
}
function unTranslateNum($num) {
static $dec_sep;
static $num_grp_sep;
global $current_user, $sugar_config;
if($dec_sep == null) {
$user_dec_sep = $current_user->getPreference('dec_sep');
$dec_sep = (empty($user_dec_sep) ? $sugar_config['default_decimal_seperator'] : $user_dec_sep);
}
if($num_grp_sep == null) {
$user_num_grp_sep = $current_user->getPreference('num_grp_sep');
$num_grp_sep = (empty($user_num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $user_num_grp_sep);
}
$num = preg_replace("'" . preg_quote($num_grp_sep) . "'", '', $num);
$num = preg_replace("'" . preg_quote($dec_sep) . "'", '.', $num);
return $num;
}
function add_http($url) {
if(!preg_match("@://@i", $url)) {
$scheme = "http";
if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
$scheme = 'https';
}
return "{$scheme}://{$url}";
}
return $url;
}
/**
* returns a default array of XSS tags to clean
* @return array
*/
function getDefaultXssTags() {
$tmp = array(
"applet" => "applet",
"base" => "base",
"embed" => "embed",
"form" => "form",
"frame" => "frame",
"frameset" => "frameset",
"iframe" => "iframe",
"import" => "\?import",
"layer" => "layer",
"link" => "link",
"object" => "object",
"script" => "script",
"xmp" => "xmp",
);
$ret = base64_encode(serialize($tmp));
return $ret;
}
/**
* Remove potential xss vectors from strings
* @param string str String to search for XSS attack vectors
* @deprecated
* @return string
*/
function remove_xss($str)
{
return SugarCleaner::cleanHtml($str, false);
}
/**
* Detects typical XSS attack patterns
* @deprecated
* @param string str String to search for XSS attack vectors
* @param bool cleanImg Flag to allow <img> tags to survive - only used by InboundEmail for inline images.
* @return array Array of matches, empty on clean string
*/
function clean_xss($str, $cleanImg=true) {
global $sugar_config;
if(empty($sugar_config['email_xss']))
$sugar_config['email_xss'] = getDefaultXssTags();
$xsstags = unserialize(base64_decode($sugar_config['email_xss']));
// cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.)
$jsEvents = "onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|";
$jsEvents .= "onmouseup|onmouseover|onmousedown|onmouseenter|onmouseleave|onmousemove|onload|onchange|";
$jsEvents .= "onreset|onselect|onsubmit|onkeydown|onkeypress|onkeyup|onabort|onerror|ondragdrop";
$attribute_regex = "#\b({$jsEvents})\s*=\s*(?|(?!['\"])\S+|['\"].+?['\"])#sim";
$javascript_regex = '@<[^/>][^>]+(expression\(|j\W*a\W*v\W*a|v\W*b\W*s\W*c\W*r|&#|/\*|\*/)[^>]*>@sim';
$imgsrc_regex = '#<[^>]+src[^=]*=([^>]*?http(s)?://[^>]*)>#sim';
$css_url = '#url\(.*\.\w+\)#';
$tagsrex = '#<\/?(\w+)((?:\s+(?:\w|\w[\w-]*\w)(?:\s*=\s*(?:\".*?\"|\'.*?\'|[^\'\">\s]+))?)+\s*|\s*)\/?>#im';
$tagmatches = array();
$matches = array();
preg_match_all($tagsrex, $str, $tagmatches, PREG_PATTERN_ORDER);
foreach($tagmatches[1] as $no => $tag) {
if(in_array($tag, $xsstags)) {
// dangerous tag - take out whole
$matches[] = $tagmatches[0][$no];
continue;
}
$attrmatch = array();
preg_match_all($attribute_regex, $tagmatches[2][$no], $attrmatch, PREG_PATTERN_ORDER);
if(!empty($attrmatch[0])) {
$matches = array_merge($matches, $attrmatch[0]);
}
}
$matches = array_merge($matches, xss_check_pattern($javascript_regex, $str));
if($cleanImg) {
$matches = array_merge($matches,
xss_check_pattern($imgsrc_regex, $str)
);
}
// cn: bug 13498 - custom white-list of allowed domains that vet remote images
preg_match_all($css_url, $str, $cssUrlMatches, PREG_PATTERN_ORDER);
if(isset($sugar_config['security_trusted_domains']) && !empty($sugar_config['security_trusted_domains']) && is_array($sugar_config['security_trusted_domains'])) {
if(is_array($cssUrlMatches) && count($cssUrlMatches) > 0) {
// normalize whitelist
foreach($sugar_config['security_trusted_domains'] as $k => $v) {
$sugar_config['security_trusted_domains'][$k] = strtolower($v);
}
foreach($cssUrlMatches[0] as $match) {
$domain = strtolower(substr(strstr($match, "://"), 3));
$baseUrl = substr($domain, 0, strpos($domain, "/"));
if(!in_array($baseUrl, $sugar_config['security_trusted_domains'])) {
$matches[] = $match;
}
}
}
} else {
$matches = array_merge($matches, $cssUrlMatches[0]);
}
return $matches;
}
/**
* Helper function used by clean_xss() to parse for known-bad vectors
* @param string pattern Regex pattern to use
* @param string str String to parse for badness
* @return array
*/
function xss_check_pattern($pattern, $str) {
preg_match_all($pattern, $str, $matches, PREG_PATTERN_ORDER);
return $matches[1];
}
/**
* Designed to take a string passed in the URL as a parameter and clean all "bad" data from it
*
* @param string $str
* @param string $filter which corresponds to a regular expression to use; choices are:
* "STANDARD" ( default )
* "STANDARDSPACE"
* "FILE"
* "NUMBER"
* "SQL_COLUMN_LIST"
* "PATH_NO_URL"
* "SAFED_GET"
* "UNIFIED_SEARCH"
* "AUTO_INCREMENT"
* "ALPHANUM"
* @param boolean $dieOnBadData true (default) if you want to die if bad data if found, false if not
*/
function clean_string($str, $filter = "STANDARD", $dieOnBadData = true)
{
global $sugar_config;
$filters = Array(
"STANDARD" => '#[^A-Z0-9\-_\.\@]#i',
"STANDARDSPACE" => '#[^A-Z0-9\-_\.\@\ ]#i',
"FILE" => '#[^A-Z0-9\-_\.]#i',
"NUMBER" => '#[^0-9\-]#i',
"SQL_COLUMN_LIST" => '#[^A-Z0-9\(\),_\.]#i',
"PATH_NO_URL" => '#://#i',
"SAFED_GET" => '#[^A-Z0-9\@\=\&\?\.\/\-_~+]#i', /* range of allowed characters in a GET string */
"UNIFIED_SEARCH" => "#[\\x00]#", /* cn: bug 3356 & 9236 - MBCS search strings */
"AUTO_INCREMENT" => '#[^0-9\-,\ ]#i',
"ALPHANUM" => '#[^A-Z0-9\-]#i',
);
if (preg_match($filters[$filter], $str)) {
if (isset($GLOBALS['log']) && is_object($GLOBALS['log'])) {
$GLOBALS['log']->fatal("SECURITY[$filter]: bad data passed in; string: {$str}");
}
if ( $dieOnBadData ) {
die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>");
}
return false;
}
else {
return $str;
}
}
function clean_special_arguments() {
if(isset($_SERVER['PHP_SELF'])) {
if (!empty($_SERVER['PHP_SELF'])) clean_string($_SERVER['PHP_SELF'], 'SAFED_GET');
}
if (!empty($_REQUEST) && !empty($_REQUEST['login_theme'])) clean_string($_REQUEST['login_theme'], "STANDARD");
if (!empty($_REQUEST) && !empty($_REQUEST['login_module'])) clean_string($_REQUEST['login_module'], "STANDARD");
if (!empty($_REQUEST) && !empty($_REQUEST['login_action'])) clean_string($_REQUEST['login_action'], "STANDARD");
if (!empty($_REQUEST) && !empty($_REQUEST['ck_login_theme_20'])) clean_string($_REQUEST['ck_login_theme_20'], "STANDARD");
if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_theme'])) clean_string($_SESSION['authenticated_user_theme'], "STANDARD");
if (!empty($_REQUEST) && !empty($_REQUEST['module_name'])) clean_string($_REQUEST['module_name'], "STANDARD");
if (!empty($_REQUEST) && !empty($_REQUEST['module'])) clean_string($_REQUEST['module'], "STANDARD");
if (!empty($_POST) && !empty($_POST['parent_type'])) clean_string($_POST['parent_type'], "STANDARD");
if (!empty($_REQUEST) && !empty($_REQUEST['mod_lang'])) clean_string($_REQUEST['mod_lang'], "STANDARD");
if (!empty($_SESSION) && !empty($_SESSION['authenticated_user_language'])) clean_string($_SESSION['authenticated_user_language'], "STANDARD");
if (!empty($_SESSION) && !empty($_SESSION['dyn_layout_file'])) clean_string($_SESSION['dyn_layout_file'], "PATH_NO_URL");
if (!empty($_GET) && !empty($_GET['from'])) clean_string($_GET['from']);
if (!empty($_GET) && !empty($_GET['gmto'])) clean_string($_GET['gmto'], "NUMBER");
if (!empty($_GET) && !empty($_GET['case_number'])) clean_string($_GET['case_number'], "AUTO_INCREMENT");
if (!empty($_GET) && !empty($_GET['bug_number'])) clean_string($_GET['bug_number'], "AUTO_INCREMENT");
if (!empty($_GET) && !empty($_GET['quote_num'])) clean_string($_GET['quote_num'], "AUTO_INCREMENT");
clean_superglobals('stamp', 'ALPHANUM'); // for vcr controls
clean_superglobals('offset', 'ALPHANUM');
clean_superglobals('return_action');
clean_superglobals('return_module');
return TRUE;
}
/**
* cleans the given key in superglobals $_GET, $_POST, $_REQUEST
*/
function clean_superglobals($key, $filter = 'STANDARD') {
if(isset($_GET[$key])) clean_string($_GET[$key], $filter);
if(isset($_POST[$key])) clean_string($_POST[$key], $filter);
if(isset($_REQUEST[$key])) clean_string($_REQUEST[$key], $filter);
}
function set_superglobals($key, $val){
$_GET[$key] = $val;
$_POST[$key] = $val;
$_REQUEST[$key] = $val;
}
// Works in conjunction with clean_string() to defeat SQL injection, file inclusion attacks, and XSS
function clean_incoming_data() {
global $sugar_config;
global $RAW_REQUEST;
if(get_magic_quotes_gpc()) {
// magic quotes screw up data, we'd have to clean up
$RAW_REQUEST = array_map("cleanup_slashes", $_REQUEST);
} else {
$RAW_REQUEST = $_REQUEST;
}
if (get_magic_quotes_gpc() == 1) {
$req = array_map("preprocess_param", $_REQUEST);
$post = array_map("preprocess_param", $_POST);
$get = array_map("preprocess_param", $_GET);
} else {
$req = array_map("securexss", $_REQUEST);
$post = array_map("securexss", $_POST);
$get = array_map("securexss", $_GET);
}
// PHP cannot stomp out superglobals reliably
foreach($post as $k => $v) { $_POST[$k] = $v; }
foreach($get as $k => $v) { $_GET[$k] = $v; }
foreach($req as $k => $v) {
$_REQUEST[$k] = $v;
//ensure the keys are safe as well. If mbstring encoding translation is on, the post keys don't
//get translated, so scrub the data but don't die
if(ini_get('mbstring.encoding_translation')==='1'){
securexsskey($k,false);
}else{
securexsskey($k,true);
}
}
// Any additional variables that need to be cleaned should be added here
if (isset($_REQUEST['login_theme'])) clean_string($_REQUEST['login_theme']);
if (isset($_REQUEST['login_module'])) clean_string($_REQUEST['login_module']);
if (isset($_REQUEST['login_action'])) clean_string($_REQUEST['login_action']);
if (isset($_REQUEST['login_language'])) clean_string($_REQUEST['login_language']);
if (isset($_REQUEST['action'])) clean_string($_REQUEST['action']);
if (isset($_REQUEST['module'])) clean_string($_REQUEST['module']);
if (isset($_REQUEST['record'])) clean_string($_REQUEST['record'], 'STANDARDSPACE');
if (isset($_SESSION['authenticated_user_theme'])) clean_string($_SESSION['authenticated_user_theme']);
if (isset($_SESSION['authenticated_user_language'])) clean_string($_SESSION['authenticated_user_language']);
if (isset($_REQUEST['language'])) clean_string($_REQUEST['language']);
if (isset($sugar_config['default_theme'])) clean_string($sugar_config['default_theme']);
if (isset($_REQUEST['offset'])) clean_string($_REQUEST['offset']);
if (isset($_REQUEST['stamp'])) clean_string($_REQUEST['stamp']);
if(isset($_REQUEST['lvso'])){
set_superglobals('lvso', (strtolower($_REQUEST['lvso']) === 'desc')?'desc':'asc');
}
// Clean "offset" and "order_by" parameters in URL
foreach ($_REQUEST as $key => $val) {
if (str_end($key, "_offset")) {
clean_string($_REQUEST[$key], "ALPHANUM"); // keep this ALPHANUM for disable_count_query
set_superglobals($key, $_REQUEST[$key]);
}
elseif (str_end($key, "_ORDER_BY")) {
clean_string($_REQUEST[$key], "SQL_COLUMN_LIST");
set_superglobals($key, $_REQUEST[$key]);
}
}
return 0;
}
// Returns TRUE if $str begins with $begin
function str_begin($str, $begin) {
return (substr($str, 0, strlen($begin)) == $begin);
}
// Returns TRUE if $str ends with $end
function str_end($str, $end) {
return (substr($str, strlen($str) - strlen($end)) == $end);
}
function securexss($value) {
if(is_array($value)){
$new = array();
foreach($value as $key=>$val){
$new[$key] = securexss($val);
}
return $new;
}
static $xss_cleanup= array("&quot;" => "&#38;", '"' =>'&quot;', "'" => '&#039;' , '<' =>'&lt;' , '>'=>'&gt;');
$value = preg_replace(array('/javascript:/i', '/\0/'), array('java script:', ''), $value);
$value = preg_replace('/javascript:/i', 'java script:', $value);
return str_replace(array_keys($xss_cleanup), array_values($xss_cleanup), $value);
}
function securexsskey($value, $die=true){
global $sugar_config;
$matches = array();
preg_match('/[\'"<>]/', $value, $matches);
if(!empty($matches)){
if($die){
die("Bad data passed in; <a href=\"{$sugar_config['site_url']}\">Return to Home</a>");
}else{
unset($_REQUEST[$value]);
unset($_POST[$value]);
unset($_GET[$value]);
}
}
}
function preprocess_param($value){
if(is_string($value)){
if(get_magic_quotes_gpc() == 1){
$value = stripslashes($value);
}
$value = securexss($value);
}
return $value;
}
function cleanup_slashes($value)
{
if(is_string($value)) return stripslashes($value);
return $value;
}
function set_register_value($category, $name, $value){
return sugar_cache_put("{$category}:{$name}", $value);
}
function get_register_value($category,$name){
return sugar_cache_retrieve("{$category}:{$name}");
}
function clear_register_value($category,$name){
return sugar_cache_clear("{$category}:{$name}");
}
// this function cleans id's when being imported
function convert_id($string)
{
return preg_replace_callback( '|[^A-Za-z0-9\-]|',
create_function(
// single quotes are essential here,
// or alternative escape all $ as \$
'$matches',
'return ord($matches[0]);'
) ,$string);
}
/**
* @deprecated use SugarTheme::getImage()
*/
function get_image($image,$other_attributes,$width="",$height="",$ext='.gif',$alt="")
{
return SugarThemeRegistry::current()->getImage(basename($image), $other_attributes, empty($width) ? null : $width, empty($height) ? null : $height, $ext, $alt );
}
/**
* @deprecated use SugarTheme::getImageURL()
*/
function getImagePath($image_name)
{
return SugarThemeRegistry::current()->getImageURL($image_name);
}
function getWebPath($relative_path){
//if it has a :// then it isn't a relative path
if(substr_count($relative_path, '://') > 0) return $relative_path;
if(defined('TEMPLATE_URL'))$relative_path = SugarTemplateUtilities::getWebPath($relative_path);
return $relative_path;
}
function getVersionedPath($path, $additional_attrs='')
{
if(empty($GLOBALS['sugar_config']['js_custom_version'])) $GLOBALS['sugar_config']['js_custom_version'] = 1;
$js_version_key = isset($GLOBALS['js_version_key'])?$GLOBALS['js_version_key']:'';
if(inDeveloperMode()) {
static $rand;
if(empty($rand)) $rand = mt_rand();
$dev = $rand;
} else {
$dev = '';
}
if(is_array($additional_attrs)) {
$additional_attrs = join("|",$additional_attrs);
}
// cutting 2 last chars here because since md5 is 32 chars, it's always ==
$str = substr(base64_encode(md5("$js_version_key|{$GLOBALS['sugar_config']['js_custom_version']}|$dev|$additional_attrs", true)), 0, -2);
// remove / - it confuses some parsers
$str = strtr($str, '/+', '-_');
if(empty($path)) return $str;
return $path . "?v=$str";
}
function getVersionedScript($path, $additional_attrs='')
{
return '<script type="text/javascript" src="'.getVersionedPath($path, $additional_attrs).'"></script>';
}
function getJSPath($relative_path, $additional_attrs='')
{
if(defined('TEMPLATE_URL'))$relative_path = SugarTemplateUtilities::getWebPath($relative_path);
return getVersionedPath($relative_path).(!empty($additional_attrs)?"&$additional_attrs":"");
}
function getSWFPath($relative_path, $additional_params=''){
$path = $relative_path;
if (!empty($additional_params)){
$path .= '?' . $additional_params;
}
if (defined('TEMPLATE_URL')){
$path = TEMPLATE_URL . '/' . $path;
}
return $path;
}
function getSQLDate($date_str)
{
if (preg_match('/^(\d{1,2})-(\d{1,2})-(\d{4})$/',$date_str,$match))
{
if ( strlen($match[2]) == 1)
{
$match[2] = "0".$match[2];
}
if ( strlen($match[1]) == 1)
{
$match[1] = "0".$match[1];
}
return "{$match[3]}-{$match[1]}-{$match[2]}";
}
else if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/',$date_str,$match))
{
if ( strlen($match[2]) == 1)
{
$match[2] = "0".$match[2];
}
if ( strlen($match[1]) == 1)
{
$match[1] = "0".$match[1];
}
return "{$match[3]}-{$match[1]}-{$match[2]}";
}
else
{
return "";
}
}
function clone_history(&$db, $from_id,$to_id, $to_type)
{
global $timedate;
$old_note_id=null;
$old_filename=null;
require_once('include/upload_file.php');
$tables = array('calls'=>'Call', 'meetings'=>'Meeting', 'notes'=>'Note', 'tasks'=>'Task');
$location=array('Email'=>"modules/Emails/Email.php",
'Call'=>"modules/Calls/Call.php",
'Meeting'=>"modules/Meetings/Meeting.php",
'Note'=>"modules/Notes/Note.php",
'Tasks'=>"modules/Tasks/Task.php",
);
foreach($tables as $table=>$bean_class)
{
if (!class_exists($bean_class))
{
require_once($location[$bean_class]);
}
$bProcessingNotes=false;
if ($table=='notes')
{
$bProcessingNotes=true;
}
$query = "SELECT id FROM $table WHERE parent_id='$from_id'";
$results = $db->query($query);
while($row = $db->fetchByAssoc($results))
{
//retrieve existing record.
$bean= new $bean_class();
$bean->retrieve($row['id']);
//process for new instance.
if ($bProcessingNotes)
{
$old_note_id=$row['id'];
$old_filename=$bean->filename;
}
$bean->id=null;
$bean->parent_id=$to_id;
$bean->parent_type=$to_type;
if ($to_type=='Contacts' and in_array('contact_id',$bean->column_fields))
{
$bean->contact_id=$to_id;
}
$bean->update_date_modified = false;
$bean->update_modified_by = false;
if(isset($bean->date_modified))
$bean->date_modified = $timedate->to_db($bean->date_modified);
if(isset($bean->date_entered))
$bean->date_entered = $timedate->to_db($bean->date_entered);
//save
$new_id=$bean->save();
//duplicate the file now. for notes.
if ($bProcessingNotes && !empty($old_filename))
{
UploadFile::duplicate_file($old_note_id,$new_id,$old_filename);
}
//reset the values needed for attachment duplication.
$old_note_id=null;
$old_filename=null;
}
}
}
function values_to_keys($array)
{
$new_array = array();
if(!is_array($array))
{
return $new_array;
}
foreach($array as $arr){
$new_array[$arr] = $arr;
}
return $new_array;
}
function clone_relationship(&$db, $tables = array(), $from_column, $from_id, $to_id)
{
foreach($tables as $table)
{
if ($table == 'emails_beans') {
$query = "SELECT * FROM $table WHERE $from_column='$from_id' and bean_module='Leads'";
} else {
$query = "SELECT * FROM $table WHERE $from_column='$from_id'";
}
$results = $db->query($query);
while($row = $db->fetchByAssoc($results))
{
$query = "INSERT INTO $table ";
$names = '';
$values = '';
$row[$from_column] = $to_id;
$row['id'] = create_guid();
if ($table=='emails_beans') {
$row['bean_module'] =='Contacts';
}
foreach($row as $name=>$value)
{
if(empty($names))
{
$names .= $name;
$values .= "'$value'";
} else
{
$names .= ', '. $name;
$values .= ", '$value'";
}
}
$query .= "($names) VALUES ($values)";
$db->query($query);
}
}
}
function get_unlinked_email_query($type, $bean) {
global $current_user;
$return_array['select']='SELECT emails.id ';
$return_array['from']='FROM emails ';
$return_array['where']="";
$return_array['join'] = " JOIN (select DISTINCT email_id from emails_email_addr_rel eear
join email_addr_bean_rel eabr on eabr.bean_id ='$bean->id' and eabr.bean_module = '$bean->module_dir' and
eabr.email_address_id = eear.email_address_id and eabr.deleted=0
where eear.deleted=0 and eear.email_id not in
(select eb.email_id from emails_beans eb where eb.bean_module ='$bean->module_dir' and eb.bean_id = '$bean->id')
) derivedemails on derivedemails.email_id = emails.id";
$return_array['join_tables'][0] = '';
if (isset($type) and !empty($type['return_as_array'])) {
return $return_array;
}
return $return_array['select'] . $return_array['from'] . $return_array['where'] . $return_array['join'] ;
} // fn
function get_emails_by_assign_or_link($params)
{
$relation = $params['link'];
$bean = $GLOBALS['app']->controller->bean;
if(empty($bean->$relation)) {
$bean->load_relationship($relation);
}
if(empty($bean->$relation)) {
$GLOBALS['log']->error("Bad relation '$relation' for bean '{$bean->object_name}' id '{$bean->id}'");
return array();
}
$rel_module = $bean->$relation->getRelatedModuleName();
$rel_join = $bean->$relation->getJoin(array(
'join_table_alias' => 'link_bean',
'join_table_link_alias' => 'linkt',
));
$rel_join = str_replace("{$bean->table_name}.id", "'{$bean->id}'", $rel_join);
$return_array['select']='SELECT emails.id ';
$return_array['from'] = "FROM emails ";
$return_array['join'] = " INNER JOIN (".
// directly assigned emails
"select eb.email_id, 'direct' source FROM emails_beans eb where eb.bean_module = '{$bean->module_dir}' AND eb.bean_id = '{$bean->id}' AND eb.deleted=0 ".
" UNION ".
// Assigned to contacts
"select DISTINCT eb.email_id, 'contact' source FROM emails_beans eb
$rel_join AND link_bean.id = eb.bean_id
where eb.bean_module = '$rel_module' AND eb.deleted=0".
" UNION ".
// Related by directly by email
"select DISTINCT eear.email_id, 'relate' source from emails_email_addr_rel eear INNER JOIN email_addr_bean_rel eabr
ON eabr.bean_id ='{$bean->id}' AND eabr.bean_module = '{$bean->module_dir}' AND
eabr.email_address_id = eear.email_address_id and eabr.deleted=0 where eear.deleted=0".
" UNION ".
// Related by email to linked contact
"select DISTINCT eear.email_id, 'relate_contact' source FROM emails_email_addr_rel eear INNER JOIN email_addr_bean_rel eabr
ON eabr.email_address_id=eear.email_address_id AND eabr.bean_module = '$rel_module' AND eabr.deleted=0
$rel_join AND link_bean.id = eabr.bean_id
where eear.deleted=0".
") email_ids ON emails.id=email_ids.email_id ";
$return_array['where']=" WHERE emails.deleted=0 ";
//$return_array['join'] = '';
$return_array['join_tables'][0] = '';
if($bean->object_name == "Case" && !empty($bean->case_number)) {
$where = str_replace("%1", $bean->case_number, $bean->getEmailSubjectMacro());
$return_array["where"] .= "\n AND (email_ids.source = 'direct' OR emails.name LIKE '%$where%')";
}
return $return_array;
}
/**
* Check to see if the number is empty or non-zero
* @param $value
* @return boolean
**/
function number_empty($value)
{
return empty($value) && $value != '0';
}
function get_bean_select_array($add_blank=true, $bean_name, $display_columns, $where='', $order_by='', $blank_is_none=false)
{
global $beanFiles;
require_once($beanFiles[$bean_name]);
$focus = new $bean_name();
$user_array = array();
$key = ($bean_name == 'EmailTemplate') ? $bean_name : $bean_name . $display_columns. $where . $order_by;
$user_array = get_register_value('select_array', $key );
if(!$user_array)
{
$db = DBManagerFactory::getInstance();
$temp_result = Array();
$query = "SELECT {$focus->table_name}.id, {$display_columns} as display from {$focus->table_name} ";
$query .= "where ";
if ( $where != '')
{
$query .= $where." AND ";
}
$query .= " {$focus->table_name}.deleted=0";
if ( $order_by != '')
{
$query .= " order by {$focus->table_name}.{$order_by}";
}
$GLOBALS['log']->debug("get_user_array query: $query");
$result = $db->query($query, true, "Error filling in user array: ");
if ($add_blank==true){
// Add in a blank row
if($blank_is_none == true) { // set 'blank row' to "--None--"
global $app_strings;
$temp_result[''] = $app_strings['LBL_NONE'];
} else {
$temp_result[''] = '';
}
}
// Get the id and the name.
while($row = $db->fetchByAssoc($result))
{
$temp_result[$row['id']] = $row['display'];
}
$user_array = $temp_result;
set_register_value('select_array', $key ,$temp_result);
}
return $user_array;
}
/**
*
*
* @param unknown_type $listArray
*/
// function parse_list_modules
// searches a list for items in a user's allowed tabs and returns an array that removes unallowed tabs from list
function parse_list_modules(&$listArray)
{
global $modListHeader;
$returnArray = array();
foreach($listArray as $optionName => $optionVal)
{
if(array_key_exists($optionName, $modListHeader))
{
$returnArray[$optionName] = $optionVal;
}
// special case for projects
if(array_key_exists('Project', $modListHeader))
{
$returnArray['ProjectTask'] = $listArray['ProjectTask'];
}
}
$acldenied = ACLController::disabledModuleList($listArray,false);
foreach($acldenied as $denied){
unset($returnArray[$denied]);
}
asort($returnArray);
return $returnArray;
}
function display_notice($msg = false){
global $error_notice;
//no error notice - lets just display the error to the user
if(!isset($error_notice)){
echo '<br>'.$msg . '<br>';
}else{
$error_notice .= $msg . '<br>';
}
}
/* checks if it is a number that at least has the plus at the beginning.
*/
function skype_formatted($number){
//kbrill - BUG #15375
if(isset($_REQUEST['action']) && $_REQUEST['action']=="Popup") {
return false;
} else {
return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 3) == '011';
}
// return substr($number, 0, 1) == '+' || substr($number, 0, 2) == '00' || substr($number, 0, 2) == '011';
}
function format_skype($number) {
return preg_replace('/[^\+0-9]/','',$number);
}
function insert_charset_header() {
header('Content-Type: text/html; charset=UTF-8');
}
function getCurrentURL()
{
$href = "http:";
if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')
{
$href = 'https:';
}
$href.= "//".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING'];
return $href;
}
function javascript_escape($str) {
$new_str = '';
for($i = 0; $i < strlen($str); $i++) {
if(ord(substr($str, $i, 1))==10){
$new_str .= '\n';
}elseif(ord(substr($str, $i, 1))==13){
$new_str .= '\r';
}
else {
$new_str .= $str{$i};
}
}
$new_str = str_replace("'", "\\'", $new_str);
return $new_str;
}
function js_escape($str, $keep=true){
$str = html_entity_decode(str_replace("\\", "", $str), ENT_QUOTES);
if($keep){
$str = javascript_escape($str);
}
else {
$str = str_replace("'", " ", $str);
$str = str_replace('"', " ", $str);
}
return $str;
//end function js_escape
}
function br2nl($str) {
$regex = "#<[^>]+br.+?>#i";
preg_match_all($regex, $str, $matches);
foreach($matches[0] as $match) {
$str = str_replace($match, "<br>", $str);
}
$brs = array('<br>','<br/>', '<br />');
$str = str_replace("\r\n", "\n", $str); // make from windows-returns, *nix-returns
$str = str_replace("\n\r", "\n", $str); // make from windows-returns, *nix-returns
$str = str_replace("\r", "\n", $str); // make from windows-returns, *nix-returns
$str = str_ireplace($brs, "\n", $str); // to retrieve it
return $str;
}
/**
* Private helper function for displaying the contents of a given variable.
* This function is only intended to be used for SugarCRM internal development.
* The ppd stands for Pre Print Die.
*/
function _ppd($mixed)
{
}
/**
* Private helper function for displaying the contents of a given variable in
* the Logger. This function is only intended to be used for SugarCRM internal
* development. The pp stands for Pre Print.
* @param $mixed var to print_r()
* @param $die boolean end script flow
* @param $displayStackTrace also show stack trace
*/
function _ppl($mixed, $die=false, $displayStackTrace=false, $loglevel="fatal") {
if(!isset($GLOBALS['log']) || empty($GLOBALS['log'])) {
$GLOBALS['log'] = LoggerManager :: getLogger('SugarCRM');
}
$mix = print_r($mixed, true); // send print_r() output to $mix
$stack = debug_backtrace();
$GLOBALS['log']->$loglevel('------------------------------ _ppLogger() output start -----------------------------');
$GLOBALS['log']->$loglevel($mix);
if($displayStackTrace) {
foreach($stack as $position) {
$GLOBALS['log']->$loglevel($position['file']."({$position['line']})");
}
}
$GLOBALS['log']->$loglevel('------------------------------ _ppLogger() output end -----------------------------');
$GLOBALS['log']->$loglevel('------------------------------ _ppLogger() file: '.$stack[0]['file'].' line#: '.$stack[0]['line'].'-----------------------------');
if($die) {
die();
}
}
/**
* private helper function to quickly show the major, direct, field attributes of a given bean.
* The ppf stands for Pre[formatted] Print Focus [object]
* @param object bean The focus bean
*/
function _ppf($bean, $die=false) {
}
/**
* Private helper function for displaying the contents of a given variable.
* This function is only intended to be used for SugarCRM internal development.
* The pp stands for Pre Print.
*/
function _pp($mixed)
{
}
/**
* Private helper function for displaying the contents of a given variable.
* This function is only intended to be used for SugarCRM internal development.
* The pp stands for Pre Print.
*/
function _pstack_trace($mixed=NULL)
{
}
/**
* Private helper function for displaying the contents of a given variable.
* This function is only intended to be used for SugarCRM internal development.
* The pp stands for Pre Print Trace.
*/
function _ppt($mixed, $textOnly=false)
{
}
/**
* Private helper function for displaying the contents of a given variable.
* This function is only intended to be used for SugarCRM internal development.
* The pp stands for Pre Print Trace Die.
*/
function _pptd($mixed)
{
}
/**
* Private helper function for decoding javascript UTF8
* This function is only intended to be used for SugarCRM internal development.
*/
function decodeJavascriptUTF8($str) {
}
/**
* Will check if a given PHP version string is supported (tested on this ver),
* unsupported (results unknown), or invalid (something will break on this
* ver). Do not pass in any pararameter to default to a check against the
* current environment's PHP version.
*
* @return 1 implies supported, 0 implies unsupported, -1 implies invalid
*/
function check_php_version($sys_php_version = '') {
$sys_php_version = empty($sys_php_version) ? constant('PHP_VERSION') : $sys_php_version;
// versions below $min_considered_php_version considered invalid by default,
// versions equal to or above this ver will be considered depending
// on the rules that follow
$min_considered_php_version = '5.2.1';
// only the supported versions,
// should be mutually exclusive with $invalid_php_versions
$supported_php_versions = array (
'5.2.1', '5.2.2', '5.2.3', '5.2.4', '5.2.5', '5.2.6', '5.2.8', '5.3.0'
);
// invalid versions above the $min_considered_php_version,
// should be mutually exclusive with $supported_php_versions
// SugarCRM prohibits install on PHP 5.2.7 on all platforms
$invalid_php_versions = array('5.2.7');
// default unsupported
$retval = 0;
// versions below $min_considered_php_version are invalid
if(1 == version_compare($sys_php_version, $min_considered_php_version, '<')) {
$retval = -1;
}
// supported version check overrides default unsupported
foreach($supported_php_versions as $ver) {
if(1 == version_compare($sys_php_version, $ver, 'eq') || strpos($sys_php_version,$ver) !== false) {
$retval = 1;
break;
}
}
// invalid version check overrides default unsupported
foreach($invalid_php_versions as $ver) {
if(1 == version_compare($sys_php_version, $ver, 'eq') && strpos($sys_php_version,$ver) !== false) {
$retval = -1;
break;
}
}
//allow a redhat distro to install, regardless of version. We are assuming the redhat naming convention is followed
//and the php version contains 'rh' characters
if(strpos($sys_php_version, 'rh') !== false) {
$retval = 1;
}
return $retval;
}
/**
* Will check if a given IIS version string is supported (tested on this ver),
* unsupported (results unknown), or invalid (something will break on this
* ver).
*
* @return 1 implies supported, 0 implies unsupported, -1 implies invalid
*/
function check_iis_version($sys_iis_version = '') {
$server_software = $_SERVER["SERVER_SOFTWARE"];
$iis_version = '';
if(strpos($server_software,'Microsoft-IIS') !== false && preg_match_all("/^.*\/(\d+\.?\d*)$/", $server_software, $out))
$iis_version = $out[1][0];
$sys_iis_version = empty($sys_iis_version) ? $iis_version : $sys_iis_version;
// versions below $min_considered_iis_version considered invalid by default,
// versions equal to or above this ver will be considered depending
// on the rules that follow
$min_considered_iis_version = '6.0';
// only the supported versions,
// should be mutually exclusive with $invalid_iis_versions
$supported_iis_versions = array ('6.0', '7.0',);
$unsupported_iis_versions = array();
$invalid_iis_versions = array('5.0',);
// default unsupported
$retval = 0;
// versions below $min_considered_iis_version are invalid
if(1 == version_compare($sys_iis_version, $min_considered_iis_version, '<')) {
$retval = -1;
}
// supported version check overrides default unsupported
foreach($supported_iis_versions as $ver) {
if(1 == version_compare($sys_iis_version, $ver, 'eq') || strpos($sys_iis_version,$ver) !== false) {
$retval = 1;
break;
}
}
// unsupported version check overrides default unsupported
foreach($unsupported_iis_versions as $ver) {
if(1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version,$ver) !== false) {
$retval = 0;
break;
}
}
// invalid version check overrides default unsupported
foreach($invalid_iis_versions as $ver) {
if(1 == version_compare($sys_iis_version, $ver, 'eq') && strpos($sys_iis_version,$ver) !== false) {
$retval = -1;
break;
}
}
return $retval;
}
function pre_login_check(){
global $action, $login_error;
if(!empty($action)&& $action == 'Login'){
if(!empty($login_error)){
$login_error = htmlentities($login_error);
$login_error = str_replace(array("&lt;pre&gt;","&lt;/pre&gt;","\r\n", "\n"), "<br>", $login_error);
$_SESSION['login_error'] = $login_error;
echo '<script>
function set_focus() {}
if(document.getElementById("post_error")) {
document.getElementById("post_error").innerHTML="'. $login_error. '";
document.getElementById("cant_login").value=1;
document.getElementById("login_button").disabled = true;
document.getElementById("user_name").disabled = true;
//document.getElementById("user_password").disabled = true;
}
</script>';
}
}
}
function sugar_cleanup($exit = false) {
static $called = false;
if($called)return;
$called = true;
set_include_path(realpath(dirname(__FILE__) . '/..') . PATH_SEPARATOR . get_include_path());
chdir(realpath(dirname(__FILE__) . '/..'));
global $sugar_config;
require_once('include/utils/LogicHook.php');
LogicHook::initialize();
$GLOBALS['logic_hook']->call_custom_logic('', 'server_round_trip');
//added this check to avoid errors during install.
if (empty($sugar_config['dbconfig'])) {
if ($exit) exit; else return;
}
if (!class_exists('Tracker', true)) {
require_once 'modules/Trackers/Tracker.php';
}
Tracker::logPage();
// Now write the cached tracker_queries
if(!empty($GLOBALS['savePreferencesToDB']) && $GLOBALS['savePreferencesToDB']) {
if ( isset($GLOBALS['current_user']) && $GLOBALS['current_user'] instanceOf User )
$GLOBALS['current_user']->savePreferencesToDB();
}
//check to see if this is not an `ajax call AND the user preference error flag is set
if(
(isset($_SESSION['USER_PREFRENCE_ERRORS']) && $_SESSION['USER_PREFRENCE_ERRORS'])
&& ($_REQUEST['action']!='modulelistmenu' && $_REQUEST['action']!='DynamicAction')
&& ($_REQUEST['action']!='favorites' && $_REQUEST['action']!='DynamicAction')
&& (empty($_REQUEST['to_pdf']) || !$_REQUEST['to_pdf'] )
&& (empty($_REQUEST['sugar_body_only']) || !$_REQUEST['sugar_body_only'] )
){
global $app_strings;
//this is not an ajax call and the user preference error flag is set, so reset the flag and print js to flash message
$err_mess = $app_strings['ERROR_USER_PREFS'];
$_SESSION['USER_PREFRENCE_ERRORS'] = false;
echo "
<script>
ajaxStatus.flashStatus('$err_mess',7000);
</script>";
}
pre_login_check();
if(class_exists('DBManagerFactory')) {
$db = DBManagerFactory::getInstance();
$db->disconnect();
if($exit) {
exit;
}
}
}
register_shutdown_function('sugar_cleanup');
/*
check_logic_hook - checks to see if your custom logic is in the logic file
if not, it will add it. If the file isn't built yet, it will create the file