Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

soap/SoapHelperFunctions.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

Code
1
<?php
2
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
7
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41
42
/**
43
 * Retrieve field data for a provided SugarBean.
44
 *
45
 * @param SugarBean $value -- The bean to retrieve the field information for.
46
 * @return Array -- 'field'=>   'name' -- the name of the field
47
 *                              'type' -- the data type of the field
48
 *                              'label' -- the translation key for the label of the field
49
 *                              'required' -- Is the field required?
50
 *                              'options' -- Possible values for a drop down field
51
 */
52
function get_field_list($value, $translate=true){
53
	$list = array();
54
55
	if(!empty($value->field_defs)){
56
57
		foreach($value->field_defs as $var){
58
			if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate'))continue;
59
			$required = 0;
60
			$options_dom = array();
61
			$options_ret = array();
62
			// Apparently the only purpose of this check is to make sure we only return fields
63
			//   when we've read a record.  Otherwise this function is identical to get_module_field_list
64
			if(!empty($var['required'])) {
65
				$required = 1;
66
			}
67
			if(isset($var['options'])){
68
				$options_dom = translate($var['options'], $value->module_dir);
69
				if(!is_array($options_dom)) $options_dom = array();
70
				foreach($options_dom as $key=>$oneOption)
71
					$options_ret[] = get_name_value($key,$oneOption);
72
			}
73
74
            if(!empty($var['dbType']) && $var['type'] == 'bool') {
75
                $options_ret[] = get_name_value('type', $var['dbType']);
76
            }
77
78
            $entry = array();
79
            $entry['name'] = $var['name'];
80
            $entry['type'] = $var['type'];
81
            if($translate) {
82
            $entry['label'] = isset($var['vname']) ? translate($var['vname'], $value->module_dir) : $var['name'];
83
            } else {
84
            $entry['label'] = isset($var['vname']) ? $var['vname'] : $var['name'];
85
            }
86
            $entry['required'] = $required;
87
            $entry['options'] = $options_ret;
88
			if(isset($var['default'])) {
89
			   $entry['default_value'] = $var['default'];
90
			}
91
92
			$list[$var['name']] = $entry;
93
		} //foreach
94
	} //if
95
96
    if (isset($value->module_dir) && $value->module_dir == 'Bugs') {
97
98
		$seedRelease = new Release();
99
		$options = $seedRelease->get_releases(TRUE, "Active");
100
		$options_ret = array();
101
		foreach($options as $name=>$value){
102
			$options_ret[] =  array('name'=> $name , 'value'=>$value);
103
		}
104
		if(isset($list['fixed_in_release'])){
105
			$list['fixed_in_release']['type'] = 'enum';
106
			$list['fixed_in_release']['options'] = $options_ret;
107
		}
108
		if(isset($list['release'])){
109
			$list['release']['type'] = 'enum';
110
			$list['release']['options'] = $options_ret;
111
		}
112
		if(isset($list['release_name'])){
113
			$list['release_name']['type'] = 'enum';
114
			$list['release_name']['options'] = $options_ret;
115
		}
116
	}
117
    if (isset($value->module_dir) && $value->module_dir == 'Emails') {
118
        $fields = array('from_addr_name', 'reply_to_addr', 'to_addrs_names', 'cc_addrs_names', 'bcc_addrs_names');
119
        foreach($fields as $field){
120
            $var = $value->field_defs[$field];
121
122
            $required = 0;
123
            $entry = array();
124
            $entry['name'] = $var['name'];
125
            $entry['type'] = $var['type'];
126
            if($translate) {
127
            $entry['label'] = isset($var['vname']) ? translate($var['vname'], $value->module_dir) : $var['name'];
128
            } else {
129
            $entry['label'] = isset($var['vname']) ? $var['vname'] : $var['name'];
130
            }
131
            $entry['required'] = $required;
132
            $entry['options'] = array();
133
			if(isset($var['default'])) {
134
			   $entry['default_value'] = $var['default'];
135
			}
136
137
			$list[$var['name']] = $entry;
138
        }
139
    }
140
141
	if(isset($value->assigned_user_name) && isset($list['assigned_user_id'])) {
142
		$list['assigned_user_name'] = $list['assigned_user_id'];
143
		$list['assigned_user_name']['name'] = 'assigned_user_name';
144
	}
145
	if(isset($list['modified_user_id'])) {
146
		$list['modified_by_name'] = $list['modified_user_id'];
147
		$list['modified_by_name']['name'] = 'modified_by_name';
148
	}
149
	if(isset($list['created_by'])) {
150
		$list['created_by_name'] = $list['created_by'];
151
		$list['created_by_name']['name'] = 'created_by_name';
152
	}
153
	return $list;
154
}
155
156
function new_get_field_list($value, $translate=true) {
157
	$module_fields = array();
158
	$link_fields = array();
159
160
	if(!empty($value->field_defs)){
161
162
		foreach($value->field_defs as $var){
163
			if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'non-db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate'))continue;
164
			if ($var['source'] == 'non_db' && (isset($var['type']) && $var['type'] != 'link')) {
165
				continue;
166
			}
167
			$required = 0;
168
			$options_dom = array();
169
			$options_ret = array();
170
			// Apparently the only purpose of this check is to make sure we only return fields
171
			//   when we've read a record.  Otherwise this function is identical to get_module_field_list
172
			if(!empty($var['required'])) {
173
				$required = 1;
174
			}
175
			if(isset($var['options'])){
176
				$options_dom = translate($var['options'], $value->module_dir);
177
				if(!is_array($options_dom)) $options_dom = array();
178
				foreach($options_dom as $key=>$oneOption)
179
					$options_ret[] = get_name_value($key,$oneOption);
180
			}
181
182
            if(!empty($var['dbType']) && $var['type'] == 'bool') {
183
                $options_ret[] = get_name_value('type', $var['dbType']);
184
            }
185
186
            $entry = array();
187
            $entry['name'] = $var['name'];
188
            $entry['type'] = $var['type'];
189
            if ($var['type'] == 'link') {
190
	            $entry['relationship'] = (isset($var['relationship']) ? $var['relationship'] : '');
191
	            $entry['module'] = (isset($var['module']) ? $var['module'] : '');
192
	            $entry['bean_name'] = (isset($var['bean_name']) ? $var['bean_name'] : '');
193
				$link_fields[$var['name']] = $entry;
194
            } else {
195
	            if($translate) {
196
	            	$entry['label'] = isset($var['vname']) ? translate($var['vname'], $value->module_dir) : $var['name'];
197
	            } else {
198
	            	$entry['label'] = isset($var['vname']) ? $var['vname'] : $var['name'];
199
	            }
200
	            $entry['required'] = $required;
201
	            $entry['options'] = $options_ret;
202
				if(isset($var['default'])) {
203
				   $entry['default_value'] = $var['default'];
204
				}
205
				$module_fields[$var['name']] = $entry;
206
            } // else
207
		} //foreach
208
	} //if
209
210
	if($value->module_dir == 'Bugs'){
211
212
		$seedRelease = new Release();
213
		$options = $seedRelease->get_releases(TRUE, "Active");
214
		$options_ret = array();
215
		foreach($options as $name=>$value){
216
			$options_ret[] =  array('name'=> $name , 'value'=>$value);
217
		}
218
		if(isset($module_fields['fixed_in_release'])){
219
			$module_fields['fixed_in_release']['type'] = 'enum';
220
			$module_fields['fixed_in_release']['options'] = $options_ret;
221
		}
222
		if(isset($module_fields['release'])){
223
			$module_fields['release']['type'] = 'enum';
224
			$module_fields['release']['options'] = $options_ret;
225
		}
226
		if(isset($module_fields['release_name'])){
227
			$module_fields['release_name']['type'] = 'enum';
228
			$module_fields['release_name']['options'] = $options_ret;
229
		}
230
	}
231
232
	if(isset($value->assigned_user_name) && isset($module_fields['assigned_user_id'])) {
233
		$module_fields['assigned_user_name'] = $module_fields['assigned_user_id'];
234
		$module_fields['assigned_user_name']['name'] = 'assigned_user_name';
235
	}
236
	if(isset($module_fields['modified_user_id'])) {
237
		$module_fields['modified_by_name'] = $module_fields['modified_user_id'];
238
		$module_fields['modified_by_name']['name'] = 'modified_by_name';
239
	}
240
	if(isset($module_fields['created_by'])) {
241
		$module_fields['created_by_name'] = $module_fields['created_by'];
242
		$module_fields['created_by_name']['name'] = 'created_by_name';
243
	}
244
245
	return array('module_fields' => $module_fields, 'link_fields' => $link_fields);
246
} // fn
247
248
function setFaultObject($errorObject) {
249
	global $soap_server_object;
250
	$soap_server_object->fault($errorObject->getFaultCode(), $errorObject->getName(), '', $errorObject->getDescription());
251
} // fn
252
253
function checkSessionAndModuleAccess($session, $login_error_key, $module_name, $access_level, $module_access_level_error_key, $errorObject) {
254
	if(!validate_authenticated($session)){
255
		$errorObject->set_error('invalid_login');
256
		setFaultObject($errorObject);
257
		return false;
258
	} // if
259
260
	global  $beanList, $beanFiles;
261
	if (!empty($module_name)) {
262
		if(empty($beanList[$module_name])){
263
			$errorObject->set_error('no_module');
264
			setFaultObject($errorObject);
265
			return false;
266
		} // if
267
		global $current_user;
268
		if(!check_modules_access($current_user, $module_name, $access_level)){
269
			$errorObject->set_error('no_access');
270
			setFaultObject($errorObject);
271
			return false;
272
		}
273
	} // if
274
	return true;
275
} // fn
276
277
function checkACLAccess($bean, $viewType, $errorObject, $error_key) {
278
	if(!$bean->ACLAccess($viewType)){
279
		$errorObject->set_error($error_key);
280
		setFaultObject($errorObject);
281
		return false;
282
	} // if
283
	return true;
284
} // fn
285
286
function get_name_value($field,$value){
287
	return array('name'=>$field, 'value'=>$value);
288
}
289
290
function get_user_module_list($user){
291
	global $app_list_strings, $current_language, $beanList, $beanFiles;
292
293
	$app_list_strings = return_app_list_strings_language($current_language);
294
	$modules = query_module_access_list($user);
295
	ACLController :: filterModuleList($modules, false);
296
	global $modInvisList;
297
298
	foreach($modInvisList as $invis){
299
		$modules[$invis] = 'read_only';
300
	}
301
302
	$actions = ACLAction::getUserActions($user->id,true);
303
	foreach($actions as $key=>$value){
304
		if(isset($value['module']) && $value['module']['access']['aclaccess'] < ACL_ALLOW_ENABLED){
305
			if ($value['module']['access']['aclaccess'] == ACL_ALLOW_DISABLED) {
306
				unset($modules[$key]);
307
			} else {
308
				$modules[$key] = 'read_only';
309
			} // else
310
		} else {
311
			$modules[$key] = '';
312
		} // else
313
	} // foreach
314
315
	//Remove all modules that don't have a beanFiles entry associated with it
316
	foreach($modules as $module_name=>$module)
317
	{
318
        if ( isset($beanList[$module_name]) ) {
319
            $class_name = $beanList[$module_name];
320
            if(empty($beanFiles[$class_name])) {
321
                unset($modules[$module_name]);
322
            }
323
        } else {
324
            unset($modules[$module_name]);
325
        }
326
	}
327
328
	return $modules;
329
330
}
331
332
function check_modules_access($user, $module_name, $action='write'){
333
	if(!isset($_SESSION['avail_modules'])){
334
		$_SESSION['avail_modules'] = get_user_module_list($user);
335
	}
336
    if(isset($_SESSION['avail_modules'][$module_name])){
337
		if($action == 'write' && $_SESSION['avail_modules'][$module_name] == 'read_only'){
338
			if(is_admin($user))return true;
339
			return false;
340
		}elseif($action == 'write' && strcmp(strtolower($module_name), 'users') == 0 && !$user->isAdminForModule($module_name)){
341
            //rrs bug: 46000 - If the client is trying to write to the Users module and is not an admin then we need to stop them
342
            return false;
343
        }
344
		return true;
345
	}
346
	return false;
347
348
}
349
350
function get_name_value_list($value, $returnDomValue = false){
351
	global $app_list_strings;
352
	$list = array();
353
	if(!empty($value->field_defs)){
354
		if(isset($value->assigned_user_name)) {
355
			$list['assigned_user_name'] = get_name_value('assigned_user_name', $value->assigned_user_name);
356
		}
357
		if(isset($value->modified_by_name)) {
358
			$list['modified_by_name'] = get_name_value('modified_by_name', $value->modified_by_name);
359
		}
360
		if(isset($value->created_by_name)) {
361
			$list['created_by_name'] = get_name_value('created_by_name', $value->created_by_name);
362
		}
363
		foreach($value->field_defs as $var){
364
			if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate')){
365
366
					if($value->module_dir == 'Emails' && (($var['name'] == 'description') || ($var['name'] == 'description_html') || ($var['name'] == 'from_addr_name') || ($var['name'] == 'reply_to_addr') || ($var['name'] == 'to_addrs_names') || ($var['name'] == 'cc_addrs_names') || ($var['name'] == 'bcc_addrs_names') || ($var['name'] == 'raw_source'))) {
367
368
					} else {
369
						continue;
370
					}
371
				}
372
373
			if(isset($value->{$var['name']})){
374
				$val = $value->{$var['name']};
375
				$type = $var['type'];
376
377
				if(strcmp($type, 'date') == 0){
378
					$val = substr($val, 0, 10);
379
				}elseif(strcmp($type, 'enum') == 0 && !empty($var['options']) && $returnDomValue){
380
					$val = $app_list_strings[$var['options']][$val];
381
				}
382
				elseif(strcmp($type, 'currency') == 0){
383
					$params = array( 'currency_symbol' => false );
384
					$val = currency_format_number($val, $params);
385
				}
386
387
				$list[$var['name']] = get_name_value($var['name'], $val);
388
			}
389
		}
390
	}
391
	return $list;
392
393
}
394
395
function filter_fields($value, $fields) {
396
	global $invalid_contact_fields;
397
	$filterFields = array();
398
	foreach($fields as $field){
399
		if (is_array($invalid_contact_fields)) {
400
			if (in_array($field, $invalid_contact_fields)) {
401
				continue;
402
			} // if
403
		} // if
404
		if (isset($value->field_defs[$field])) {
405
			$var = $value->field_defs[$field];
406
			if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate')) {
407
408
				continue;
409
			}
410
		} // if
411
        // No valid field should be caught by this quoting.
412
		$filterFields[] = getValidDBName($field);
413
	} // foreach
414
	return $filterFields;
415
} // fn
416
417
function get_name_value_list_for_fields($value, $fields) {
418
	global $app_list_strings;
419
	global $invalid_contact_fields;
420
421
	$list = array();
422
	if(!empty($value->field_defs)){
423
		if(isset($value->assigned_user_name) && in_array('assigned_user_name', $fields)) {
424
			$list['assigned_user_name'] = get_name_value('assigned_user_name', $value->assigned_user_name);
425
		}
426
		if(isset($value->modified_by_name) && in_array('modified_by_name', $fields)) {
427
			$list['modified_by_name'] = get_name_value('modified_by_name', $value->modified_by_name);
428
		}
429
		if(isset($value->created_by_name) && in_array('created_by_name', $fields)) {
430
			$list['created_by_name'] = get_name_value('created_by_name', $value->created_by_name);
431
		}
432
433
		$filterFields = filter_fields($value, $fields);
434
		foreach($filterFields as $field){
435
			$var = $value->field_defs[$field];
436
			if(isset($value->{$var['name']})){
437
				$val = $value->{$var['name']};
438
				$type = $var['type'];
439
440
				if(strcmp($type, 'date') == 0){
441
					$val = substr($val, 0, 10);
442
				}elseif(strcmp($type, 'enum') == 0 && !empty($var['options'])){
443
					$val = $app_list_strings[$var['options']][$val];
444
				}
445
446
				$list[$var['name']] = get_name_value($var['name'], $val);
447
			} // if
448
		} // foreach
449
	} // if
450
	return $list;
451
452
} // fn
453
454
455
function array_get_name_value_list($array){
456
	$list = array();
457
	foreach($array as $name=>$value){
458
459
				$list[$name] = get_name_value($name, $value);
460
	}
461
	return $list;
462
463
}
464
465
function array_get_name_value_lists($array){
466
    $list = array();
467
    foreach($array as $name=>$value){
468
        $tmp_value=$value;
469
        if(is_array($value)){
470
            $tmp_value = array();
471
            foreach($value as $k=>$v){
472
                $tmp_value[] = get_name_value($k, $v);
473
            }
474
        }
475
        $list[] = get_name_value($name, $tmp_value);
476
    }
477
    return $list;
478
}
479
480
function name_value_lists_get_array($list){
481
    $array = array();
482
    foreach($list as $key=>$value){
483
        if(isset($value['value']) && isset($value['name'])){
484
            if(is_array($value['value'])){
485
                $array[$value['name']]=array();
486
                foreach($value['value'] as $v){
487
                    $array[$value['name']][$v['name']]=$v['value'];
488
                }
489
            }else{
490
                $array[$value['name']]=$value['value'];
491
            }
492
        }
493
    }
494
    return $array;
495
}
496
497
function array_get_return_value($array, $module){
498
499
	return Array('id'=>$array['id'],
500
				'module_name'=> $module,
501
				'name_value_list'=>array_get_name_value_list($array)
502
				);
503
}
504
505
function get_return_value_for_fields($value, $module, $fields) {
506
	global $module_name, $current_user;
507
	$module_name = $module;
508
	if($module == 'Users' && $value->id != $current_user->id){
509
		$value->user_hash = '';
510
	}
511
	$value = clean_sensitive_data($value->field_defs, $value);
512
	return Array('id'=>$value->id,
513
				'module_name'=> $module,
514
				'name_value_list'=>get_name_value_list_for_fields($value, $fields)
515
				);
516
}
517
518
function getRelationshipResults($bean, $link_field_name, $link_module_fields) {
519
	global  $beanList, $beanFiles;
520
	$bean->load_relationship($link_field_name);
521
	if (isset($bean->$link_field_name)) {
522
		// get the query object for this link field
523
		$query_array = $bean->$link_field_name->getQuery(true,array(),0,'',true);
524
		$params = array();
525
		$params['joined_tables'] = $query_array['join_tables'];
526
527
		// get the related module name and instantiate a bean for that.
528
		$submodulename = $bean->$link_field_name->getRelatedModuleName();
529
		$submoduleclass = $beanList[$submodulename];
530
		require_once($beanFiles[$submoduleclass]);
531
532
		$submodule = new $submoduleclass();
533
		$filterFields = filter_fields($submodule, $link_module_fields);
534
		$relFields = $bean->$link_field_name->getRelatedFields();
535
		$roleSelect = '';
536
537
		if(!empty($relFields)){
538
			foreach($link_module_fields as $field){
539
				if(!empty($relFields[$field])){
540
					$roleSelect .= ', ' . $query_array['join_tables'][0] . '.'. $field;
541
				}
542
			}
543
		}
544
		// create a query
545
		$subquery = $submodule->create_new_list_query('','',$filterFields,$params, 0,'', true,$bean);
546
		$query =  $subquery['select'].$roleSelect .   $subquery['from'].$query_array['join']. $subquery['where'];
547
548
		$result = $submodule->db->query($query, true);
549
		$list = array();
550
		while($row = $submodule->db->fetchByAssoc($result)) {
551
			$list[] = $row;
552
		}
553
		return array('rows' => $list, 'fields_set_on_rows' => $filterFields);
554
	} else {
555
		return false;
556
	} // else
557
558
} // fn
559
560
function get_return_value_for_link_fields($bean, $module, $link_name_to_value_fields_array) {
561
	global $module_name, $current_user;
562
	$module_name = $module;
563
	if($module == 'Users' && $bean->id != $current_user->id){
564
		$bean->user_hash = '';
565
	}
566
	$bean = clean_sensitive_data($value->field_defs, $bean);
567
568
	if (empty($link_name_to_value_fields_array) || !is_array($link_name_to_value_fields_array)) {
569
		return array();
570
	}
571
572
	$link_output = array();
573
	foreach($link_name_to_value_fields_array as $link_name_value_fields) {
574
		if (!is_array($link_name_value_fields) || !isset($link_name_value_fields['name']) || !isset($link_name_value_fields['value'])) {
575
			continue;
576
		}
577
		$link_field_name = $link_name_value_fields['name'];
578
		$link_module_fields = $link_name_value_fields['value'];
579
		if (is_array($link_module_fields) && !empty($link_module_fields)) {
580
			$result = getRelationshipResults($bean, $link_field_name, $link_module_fields);
581
			if (!$result) {
582
				$link_output[] = array('name' => $link_field_name, 'records' => array());
583
				continue;
584
			}
585
			$list = $result['rows'];
586
			$filterFields = $result['fields_set_on_rows'];
587
			if ($list) {
588
				$rowArray = array();
589
				foreach($list as $row) {
590
					$nameValueArray = array();
591
					foreach ($filterFields as $field) {
592
						$nameValue = array();
593
						if (isset($row[$field])) {
594
							$nameValue['name'] = $field;
595
							$nameValue['value'] = $row[$field];
596
							$nameValueArray[] = $nameValue;
597
						} // if
598
					} // foreach
599
					$rowArray[] = $nameValueArray;
600
				} // foreach
601
				$link_output[] = array('name' => $link_field_name, 'records' => $rowArray);
602
			} // if
603
		} // if
604
	} // foreach
605
	return $link_output;
606
} // fn
607
608
/**
609
 *
610
 * @param String $module_name -- The name of the module that the primary record is from.  This name should be the name the module was developed under (changing a tab name is studio does not affect the name that should be passed into this method).
611
 * @param String $module_id -- The ID of the bean in the specified module
612
 * @param String $link_field_name - The relationship name for which to create realtionships.
613
 * @param Array $related_ids -- The array of ids for which we want to create relationships
614
 * @return true on success, false on failure
615
 */
616
function new_handle_set_relationship($module_name, $module_id, $link_field_name, $related_ids) {
617
    global  $beanList, $beanFiles;
618
619
    if(empty($beanList[$module_name])) {
620
        return false;
621
    } // if
622
    $class_name = $beanList[$module_name];
623
    require_once($beanFiles[$class_name]);
624
    $mod = new $class_name();
625
    $mod->retrieve($module_id);
626
	if(!$mod->ACLAccess('DetailView')){
627
		return false;
628
	}
629
630
    foreach($related_ids as $ids) {
631
    	$GLOBALS['log']->debug("ids = " . $ids );
632
    }
633
634
	if ($mod->load_relationship($link_field_name)) {
635
		$mod->$link_field_name->add($related_ids);
636
		return true;
637
	} else {
638
		return false;
639
	}
640
}
641
642
function new_handle_set_entries($module_name, $name_value_lists, $select_fields = FALSE) {
643
	global $beanList, $beanFiles, $app_list_strings;
644
	global $current_user;
645
646
	$ret_values = array();
647
648
	$class_name = $beanList[$module_name];
649
	require_once($beanFiles[$class_name]);
650
	$ids = array();
651
	$count = 1;
652
	$total = sizeof($name_value_lists);
653
	foreach($name_value_lists as $name_value_list){
654
		$seed = new $class_name();
655
656
		$seed->update_vcal = false;
657
		foreach($name_value_list as $value){
658
			if($value['name'] == 'id'){
659
				$seed->retrieve($value['value']);
660
				break;
661
			}
662
		}
663
664
		foreach($name_value_list as $value) {
665
			$val = $value['value'];
666
			if($seed->field_name_map[$value['name']]['type'] == 'enum'){
667
				$vardef = $seed->field_name_map[$value['name']];
668
				if(isset($app_list_strings[$vardef['options']]) && !isset($app_list_strings[$vardef['options']][$value]) ) {
669
		            if ( in_array($val,$app_list_strings[$vardef['options']]) ){
670
		                $val = array_search($val,$app_list_strings[$vardef['options']]);
671
		            }
672
		        }
673
			}
674
			$seed->{$value['name']} = $val;
675
		}
676
677
		if($count == $total){
678
			$seed->update_vcal = false;
679
		}
680
		$count++;
681
682
		//Add the account to a contact
683
		if($module_name == 'Contacts'){
684
			$GLOBALS['log']->debug('Creating Contact Account');
685
			add_create_account($seed);
686
			$duplicate_id = check_for_duplicate_contacts($seed);
687
			if($duplicate_id == null){
688
				if($seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
689
					$seed->save();
690
					if($seed->deleted == 1){
691
						$seed->mark_deleted($seed->id);
692
					}
693
					$ids[] = $seed->id;
694
				}
695
			}
696
			else{
697
				//since we found a duplicate we should set the sync flag
698
				if( $seed->ACLAccess('Save')){
699
					$seed = new $class_name();
700
					$seed->id = $duplicate_id;
701
					$seed->contacts_users_id = $current_user->id;
702
					$seed->save();
703
					$ids[] = $duplicate_id;//we have a conflict
704
				}
705
			}
706
		}
707
		else if($module_name == 'Meetings' || $module_name == 'Calls'){
708
			//we are going to check if we have a meeting in the system
709
			//with the same outlook_id. If we do find one then we will grab that
710
			//id and save it
711
			if( $seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
712
				if(empty($seed->id) && !isset($seed->id)){
713
					if(!empty($seed->outlook_id) && isset($seed->outlook_id)){
714
						//at this point we have an object that does not have
715
						//the id set, but does have the outlook_id set
716
						//so we need to query the db to find if we already
717
						//have an object with this outlook_id, if we do
718
						//then we can set the id, otherwise this is a new object
719
						$order_by = "";
720
						$query = $seed->table_name.".outlook_id = '".$GLOBALS['db']->quote($seed->outlook_id)."'";
721
						$response = $seed->get_list($order_by, $query, 0,-1,-1,0);
722
						$list = $response['list'];
723
						if(count($list) > 0){
724
							foreach($list as $value)
725
							{
726
								$seed->id = $value->id;
727
								break;
728
							}
729
						}//fi
730
					}//fi
731
				}//fi
732
				$seed->save();
733
                if($seed->deleted == 1){
734
                    $seed->mark_deleted($seed->id);
735
                }
736
				$ids[] = $seed->id;
737
			}//fi
738
		}
739
		else
740
		{
741
			if( $seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
742
				$seed->save();
743
				$ids[] = $seed->id;
744
			}
745
		}
746
747
		// if somebody is calling set_entries_detail() and wants fields returned...
748
		if ($select_fields !== FALSE) {
749
			$ret_values[$count] = array();
750
751
			foreach ($select_fields as $select_field) {
752
				if (isset($seed->$select_field)) {
753
					$ret_values[$count][] = get_name_value($select_field, $seed->$select_field);
754
				}
755
			}
756
		}
757
	}
758
759
	// handle returns for set_entries_detail() and set_entries()
760
	if ($select_fields !== FALSE) {
761
		return array(
762
			'name_value_lists' => $ret_values,
763
		);
764
	}
765
	else {
766
		return array(
767
			'ids' => $ids,
768
		);
769
	}
770
}
771
772
function get_return_value($value, $module, $returnDomValue = false){
773
	global $module_name, $current_user;
774
	$module_name = $module;
775
	if($module == 'Users' && $value->id != $current_user->id){
776
		$value->user_hash = '';
777
	}
778
	$value = clean_sensitive_data($value->field_defs, $value);
779
	return Array('id'=>$value->id,
780
				'module_name'=> $module,
781
				'name_value_list'=>get_name_value_list($value, $returnDomValue)
782
				);
783
}
784
785
786
function get_encoded_Value($value) {
787
788
    // XML 1.0 doesn't allow those...
789
    $value = preg_replace("/([\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F])/", '', $value);
790
    $value = htmlspecialchars($value, ENT_NOQUOTES, "utf-8");
791
    return "<value>$value</value>";
792
}
793
794
function get_name_value_xml($val, $module_name){
795
	$xml = '<item>';
796
			$xml .= '<id>'.$val['id'].'</id>';
797
			$xml .= '<module>'.$module_name.'</module>';
798
			$xml .= '<name_value_list>';
799
			foreach($val['name_value_list'] as $name=>$nv){
800
				$xml .= '<name_value>';
801
				$xml .= '<name>'.htmlspecialchars($nv['name']).'</name>';
802
                $xml .= get_encoded_Value($nv['value']);
803
				$xml .= '</name_value>';
804
			}
805
			$xml .= '</name_value_list>';
806
			$xml .= '</item>';
807
			return $xml;
808
}
809
810
function new_get_return_module_fields($value, $module, $translate=true){
811
	global $module_name;
812
	$module_name = $module;
813
	$result = new_get_field_list($value, $translate);
814
	return Array('module_name'=>$module,
815
				'module_fields'=> $result['module_fields'],
816
				'link_fields'=> $result['link_fields'],
817
				);
818
}
819
820
function get_return_module_fields($value, $module, $error, $translate=true){
821
	global $module_name;
822
	$module_name = $module;
823
	return Array('module_name'=>$module,
824
				'module_fields'=> get_field_list($value, $translate),
825
				'error'=>get_name_value_list($value)
826
				);
827
}
828
829
function get_return_error_value($error_num, $error_name, $error_description){
830
	return Array('number'=>$error_num,
831
				'name'=> $error_name,
832
				'description'=>	$error_description
833
				);
834
}
835
836
function filter_field_list(&$field_list, $select_fields, $module_name){
837
	return filter_return_list($field_list, $select_fields, $module_name);
838
}
839
840
841
/**
842
 * Filter the results of a list query.  Limit the fields returned.
843
 *
844
 * @param Array $output_list -- The array of list data
845
 * @param Array $select_fields -- The list of fields that should be returned.  If this array is specfied, only the fields in the array will be returned.
846
 * @param String $module_name -- The name of the module this being worked on
847
 * @return The filtered array of list data.
848
 */
849
function filter_return_list(&$output_list, $select_fields, $module_name){
850
851
	for($sug = 0; $sug < sizeof($output_list) ; $sug++){
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
852
		if($module_name == 'Contacts'){
853
			global $invalid_contact_fields;
854
			if(is_array($invalid_contact_fields)){
855
				foreach($invalid_contact_fields as $name=>$val){
856
					unset($output_list[$sug]['field_list'][$name]);
857
					unset($output_list[$sug]['name_value_list'][$name]);
858
859
				}
860
			}
861
		}
862
863
		if( !empty($output_list[$sug]['name_value_list']) && is_array($output_list[$sug]['name_value_list']) && !empty($select_fields) && is_array($select_fields)){
864
			foreach($output_list[$sug]['name_value_list'] as $name=>$value)
865
					if(!in_array($value['name'], $select_fields)){
866
						unset($output_list[$sug]['name_value_list'][$name]);
867
						unset($output_list[$sug]['field_list'][$name]);
868
					}
869
		}
870
	}
871
	return $output_list;
872
}
873
874
function login_success(){
875
	global $current_language, $sugar_config, $app_strings, $app_list_strings;
876
	$current_language = $sugar_config['default_language'];
877
	$app_strings = return_application_language($current_language);
878
	$app_list_strings = return_app_list_strings_language($current_language);
879
}
880
881
882
/*
883
 *	Given an account_name, either create the account or assign to a contact.
884
 */
885
function add_create_account($seed)
886
{
887
	global $current_user;
888
	$account_name = $seed->account_name;
889
	$account_id = $seed->account_id;
890
	$assigned_user_id = $current_user->id;
891
892
	// check if it already exists
893
    $focus = new Account();
894
    if( $focus->ACLAccess('Save')){
895
		$class = get_class($seed);
896
		$temp = new $class();
897
		$temp->retrieve($seed->id);
898
		if ((! isset($account_name) || $account_name == ''))
899
		{
900
			return;
901
		}
902
		if (!isset($seed->accounts)){
903
		    	$seed->load_relationship('accounts');
904
		}
905
906
		if($seed->account_name == '' && isset($temp->account_id)){
907
			$seed->accounts->delete($seed->id, $temp->account_id);
908
			return;
909
		}
910
911
        // attempt to find by id first
912
        $ret = $focus->retrieve($account_id, true, false);
913
914
        // if it doesn't exist by id, attempt to find by name (non-deleted)
915
        if (empty($ret))
916
        {
917
            $query = "select {$focus->table_name}.id, {$focus->table_name}.deleted from {$focus->table_name} ";
918
            $query .= " WHERE name='".$seed->db->quote($account_name)."'";
919
            $query .=" ORDER BY deleted ASC";
920
            $result = $seed->db->query($query, true);
921
922
            $row = $seed->db->fetchByAssoc($result, false);
923
924
            if (!empty($row['id']))
925
            {
926
                $focus->retrieve($row['id']);
927
            }
928
        }
929
        // if it exists by id but was deleted, just remove it entirely
930
        else if ($focus->deleted)
931
        {
932
            $query2 = "delete from {$focus->table_name} WHERE id='". $seed->db->quote($focus->id) ."'";
933
            $seed->db->query($query2, true);
934
            // it was deleted, create new
935
            $focus = BeanFactory::newBean('Accounts');
936
        }
937
938
		// if we didnt find the account, so create it
939
	    if (empty($focus->id))
940
	    {
941
	    	$focus->name = $account_name;
942
943
			if ( isset($assigned_user_id))
944
			{
945
	           $focus->assigned_user_id = $assigned_user_id;
946
	           $focus->modified_user_id = $assigned_user_id;
947
			}
948
	        $focus->save();
949
	    }
950
951
	    if($seed->accounts != null && $temp->account_id != null && $temp->account_id != $focus->id){
952
	    	$seed->accounts->delete($seed->id, $temp->account_id);
953
	    }
954
955
	    if(isset($focus->id) && $focus->id != ''){
956
			$seed->account_id = $focus->id;
957
		}
958
    }
959
}
960
961
function check_for_duplicate_contacts($seed){
962
963
	if(isset($seed->id)){
964
		return null;
965
	}
966
967
	$trimmed_email = trim($seed->email1);
968
    $trimmed_email2 = trim($seed->email2);
969
	$trimmed_last = trim($seed->last_name);
970
	$trimmed_first = trim($seed->first_name);
971
	if(!empty($trimmed_email) || !empty($trimmed_email2)){
972
973
		//obtain a list of contacts which contain the same email address
974
		$contacts = $seed->emailAddress->getBeansByEmailAddress($trimmed_email);
975
        $contacts2 = $seed->emailAddress->getBeansByEmailAddress($trimmed_email2);
976
        $contacts = array_merge($contacts, $contacts2);
977
		if(count($contacts) == 0){
978
			return null;
979
		}else{
980
            foreach($contacts as $contact){
981
				if(!empty($trimmed_last) && strcmp($trimmed_last, $contact->last_name) == 0){
982
                    if((!empty($trimmed_email) || !empty($trimmed_email2)) && (strcmp($trimmed_email, $contact->email1) == 0 || strcmp($trimmed_email, $contact->email2) == 0 || strcmp($trimmed_email2, $contact->email) == 0 || strcmp($trimmed_email2, $contact->email2) == 0)){
983
						//bug: 39234 - check if the account names are the same
984
						//if the incoming contact's account_name is empty OR it is not empty and is the same
985
						//as an existing contact's account name, then find the match.
986
                        $contact->load_relationship('accounts');
987
						if(empty($seed->account_name) || strcmp($seed->account_name, $contact->account_name) == 0){
988
						    $GLOBALS['log']->info('End: SoapHelperWebServices->check_for_duplicate_contacts - duplicte found ' . $contact->id);
989
							return $contact->id;
990
						}
991
					}
992
				}
993
			}
994
			return null;
995
		}
996
	} else {
997
        //This section of code is executed if no emails are supplied in the $seed instance
998
999
        //This query is looking for the id of Contact records that do not have a primary email address based on the matching
1000
        //first and last name and the record being not deleted.  If any such records are found we will take the first one and assume
1001
        //that it is the duplicate record
1002
	    $query = "SELECT c.id as id FROM contacts c
1003
LEFT OUTER JOIN email_addr_bean_rel eabr ON eabr.bean_id = c.id
1004
WHERE c.first_name = '{$trimmed_first}' AND c.last_name = '{$trimmed_last}' AND c.deleted = 0 AND eabr.id IS NULL";
1005
1006
        //Apply the limit query filter to this since we only need the first record
1007
        $result = $GLOBALS['db']->getOne($query);
1008
        return !empty($result) ? $result : null;
1009
    }
1010
}
1011
1012
/*
1013
 * Given a client version and a server version, determine if the right hand side(server version) is greater
1014
 *
1015
 * @param left           the client sugar version
1016
 * @param right          the server version
1017
 *
1018
 * return               true if the server version is greater or they are equal
1019
 *                      false if the client version is greater
1020
 */
1021
function is_server_version_greater($left, $right){
1022
    if(count($left) == 0 && count($right) == 0){
1023
        return false;
1024
    }
1025
    else if(count($left) == 0 || count($right) == 0){
1026
        return true;
1027
    }
1028
    else if($left[0] == $right[0]){
1029
        array_shift($left);
1030
        array_shift($right);
1031
        return is_server_version_greater($left, $right);
1032
    }
1033
    else if($left[0] < $right[0]){
1034
       return true;
1035
    }
1036
    else
1037
        return false;
1038
}
1039
1040
function getFile( $zip_file, $file_in_zip ){
1041
    $base_upgrade_dir = sugar_cached("/upgrades");
1042
    $base_tmp_upgrade_dir   = "$base_upgrade_dir/temp";
1043
    $my_zip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
1044
    unzip_file( $zip_file, $file_in_zip, $my_zip_dir );
1045
    return( "$my_zip_dir/$file_in_zip" );
1046
}
1047
1048
function getManifest( $zip_file ){
1049
    ini_set("max_execution_time", "3600");
1050
    return( getFile( $zip_file, "manifest.php" ) );
1051
}
1052
1053
if(!function_exists("get_encoded")){
1054
/*HELPER FUNCTIONS*/
1055
function get_encoded($object){
1056
		return  base64_encode(serialize($object));
1057
}
1058
function get_decoded($object){
1059
		return  unserialize(base64_decode($object));
1060
1061
}
1062
1063
/**
1064
 * decrypt a string use the TripleDES algorithm. This meant to be
1065
 * modified if the end user chooses a different algorithm
1066
 *
1067
 * @param $string - the string to decrypt
1068
 *
1069
 * @return a decrypted string if we can decrypt, the original string otherwise
1070
 */
1071
function decrypt_string($string){
1072
	if(function_exists('mcrypt_cbc')){
1073
1074
		$focus = new Administration();
1075
		$focus->retrieveSettings();
1076
		$key = '';
1077
		if(!empty($focus->settings['ldap_enc_key'])){
1078
			$key = $focus->settings['ldap_enc_key'];
1079
		}
1080
		if(empty($key))
1081
			return $string;
1082
		$buffer = $string;
1083
		$key = substr(md5($key),0,24);
1084
	    $iv = "password";
1085
	    return mcrypt_cbc(MCRYPT_3DES, $key, pack("H*", $buffer), MCRYPT_DECRYPT, $iv);
1086
	}else{
1087
		return $string;
1088
	}
1089
}
1090
1091
}
1092
1093
function canViewPath( $path, $base ){
1094
  $path = realpath( $path );
1095
  $base = realpath( $base );
1096
  return 0 !== strncmp( $path, $base, strlen( $base ) );
1097
}
1098
1099
1100
/**
1101
 * apply_values
1102
 *
1103
 * This function applies the given values to the bean object.  If it is a first time sync
1104
 * then empty values will not be copied over.
1105
 *
1106
 * @param Mixed $seed Object representing SugarBean instance
1107
 * @param Array $dataValues Array of fields/values to set on the SugarBean instance
1108
 * @param boolean $firstSync Boolean indicating whether or not this is a first time sync
1109
 */
1110
function apply_values($seed, $dataValues, $firstSync)
1111
{
1112
    if(!$seed instanceof SugarBean || !is_array($dataValues))
1113
    {
1114
        return;
1115
    }
1116
1117
    foreach($dataValues as $field=>$value)
1118
    {
1119
        if($firstSync)
1120
        {
1121
            //If this is a first sync AND the value is not empty then we set it
1122
            if(!empty($value))
1123
            {
1124
                $seed->$field = $value;
1125
            }
1126
        } else {
1127
            $seed->$field = $value;
1128
        }
1129
    }
1130
}
1131
1132
/*END HELPER*/
1133
1134
?>
1135