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.

modules/Contacts/ContactFormBase.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

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
 * Description:  Base form for contact
44
 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
45
 * All Rights Reserved.
46
 * Contributor(s): ______________________________________..
47
 ********************************************************************************/
48
49
require_once('include/SugarObjects/forms/PersonFormBase.php');
50
51
class ContactFormBase extends PersonFormBase {
52
53
var $moduleName = 'Contacts';
54
var $objectName = 'Contact';
55
56
/**
57
 * getDuplicateQuery
58
 *
59
 * This function returns the SQL String used for initial duplicate Contacts check
60
 *
61
 * @see checkForDuplicates (method), ContactFormBase.php, LeadFormBase.php, ProspectFormBase.php
62
 * @param $focus sugarbean
63
 * @param $prefix String value of prefix that may be present in $_POST variables
64
 * @return SQL String of the query that should be used for the initial duplicate lookup check
65
 */
66
public function getDuplicateQuery($focus, $prefix='')
67
{
68
	$query = 'SELECT contacts.id, contacts.first_name, contacts.last_name, contacts.title FROM contacts ';
69
70
    // Bug #46427 : Records from other Teams shown on Potential Duplicate Contacts screen during Lead Conversion
71
    // add team security
72
73
    $query .= ' where contacts.deleted = 0 AND ';
74
	if(isset($_POST[$prefix.'first_name']) && strlen($_POST[$prefix.'first_name']) != 0 && isset($_POST[$prefix.'last_name']) && strlen($_POST[$prefix.'last_name']) != 0){
75
		$query .= " contacts.first_name LIKE '". $_POST[$prefix.'first_name'] . "%' AND contacts.last_name = '". $_POST[$prefix.'last_name'] ."'";
76
	} else {
77
		$query .= " contacts.last_name = '". $_POST[$prefix.'last_name'] ."'";
78
	}
79
80
	if(!empty($_POST[$prefix.'record'])) {
81
		$query .= " AND  contacts.id != '". $_POST[$prefix.'record'] ."'";
82
	}
83
    return $query;
84
}
85
86
87
function getWideFormBody($prefix, $mod='',$formname='',  $contact = '', $portal = true){
88
89
	if(!ACLController::checkAccess('Contacts', 'edit', true)){
90
		return '';
91
	}
92
93
	if(empty($contact)){
94
        $contact = $this->getContact();
95
	}
96
97
	global $mod_strings;
98
	$temp_strings = $mod_strings;
99
	if(!empty($mod)){
100
		global $current_language;
101
		$mod_strings = return_module_language($current_language, $mod);
102
	}
103
	global $app_strings;
104
	global $current_user;
105
	global $app_list_strings;
106
	$primary_address_country_options = get_select_options_with_id($app_list_strings['countries_dom'], $contact->primary_address_country);
107
	$lbl_required_symbol = $app_strings['LBL_REQUIRED_SYMBOL'];
108
	$lbl_first_name = $mod_strings['LBL_FIRST_NAME'];
109
	$lbl_last_name = $mod_strings['LBL_LAST_NAME'];
110
	$lbl_phone = $mod_strings['LBL_OFFICE_PHONE'];
111
	$lbl_address =  $mod_strings['LBL_PRIMARY_ADDRESS'];
112
113
	if (isset($contact->assigned_user_id)) {
114
		$user_id=$contact->assigned_user_id;
115
	} else {
116
		$user_id = $current_user->id;
117
	}
118
119
	//Retrieve Email address and set email1, email2
120
	$sugarEmailAddress = new SugarEmailAddress();
121
	$sugarEmailAddress->handleLegacyRetrieve($contact);
122
  	if(!isset($contact->email1)){
123
    	$contact->email1 = '';
124
    }
125
    if(!isset($contact->email2)){
126
    	$contact->email2 = '';
127
    }
128
    if(!isset($contact->email_opt_out)){
129
    	$contact->email_opt_out = '';
130
    }
131
	$lbl_email_address = $mod_strings['LBL_EMAIL_ADDRESS'];
132
	$salutation_options=get_select_options_with_id($app_list_strings['salutation_dom'], $contact->salutation);
133
134
	if (isset($contact->lead_source)) {
135
		$lead_source_options=get_select_options_with_id($app_list_strings['lead_source_dom'], $contact->lead_source);
136
	} else {
137
		$lead_source_options=get_select_options_with_id($app_list_strings['lead_source_dom'], '');
138
	}
139
140
	$form="";
141
142
143
	if ($formname == 'ConvertProspect') {
144
		$lead_source_label = "<td scope='row'>&nbsp;</td>";
145
		$lead_source_field = "<td >&nbsp;</td>";
146
	} else {
147
		$lead_source_label = "<td scope='row' nowrap>${mod_strings['LBL_LEAD_SOURCE']}</td>";
148
		$lead_source_field = "<td ><select name='${prefix}lead_source'>$lead_source_options</select></td>";
149
	}
150
151
152
global $timedate;
153
$birthdate = '';
154
if(!empty($_REQUEST['birthdate'])){
155
    	$birthdate=$_REQUEST['birthdate'];
156
   }
157
158
159
$jsCalendarImage = SugarThemeRegistry::current()->getImageURL('jscalendar.gif');
160
$ntc_date_format = $timedate->get_user_date_format();
161
$cal_dateformat = $timedate->get_cal_date_format();
162
$lbl_required_symbol = $app_strings['LBL_REQUIRED_SYMBOL'];
163
164
$form .= <<<EOQ
165
		<input type="hidden" name="${prefix}record" value="">
166
		<input type="hidden" name="${prefix}assigned_user_id" value='${user_id}'>
167
		<table border='0' celpadding="0" cellspacing="0" width='100%'>
168
		<tr>
169
		<td nowrap scope='row'>$lbl_first_name</td>
170
		<td scope='row'>$lbl_last_name&nbsp;<span class="required">$lbl_required_symbol</span></td>
171
		<td scope='row' nowrap>${mod_strings['LBL_TITLE']}</td>
172
		<td scope='row' nowrap>${mod_strings['LBL_DEPARTMENT']}</td>
173
		</tr>
174
		<tr>
175
		<td ><select name='${prefix}salutation'>$salutation_options</select>&nbsp;<input name="${prefix}first_name" type="text" value="{$contact->first_name}"></td>
176
		<td ><input name='${prefix}last_name' type="text" value="{$contact->last_name}"></td>
177
		<td  nowrap><input name='${prefix}title' type="text" value="{$contact->title}"></td>
178
		<td  nowrap><input name='${prefix}department' type="text" value="{$contact->department}"></td>
179
		</tr>
180
		<tr>
181
		<td nowrap colspan='4' scope='row'>$lbl_address</td>
182
		</tr>
183
184
		<tr>
185
		<td nowrap colspan='4' ><textarea cols='80' rows='2' name='${prefix}primary_address_street'>{$contact->primary_address_street}</textarea></td>
186
		</tr>
187
188
		<tr>
189
		<td scope='row'>${mod_strings['LBL_CITY']}</td>
190
		<td scope='row'>${mod_strings['LBL_STATE']}</td>
191
		<td scope='row'>${mod_strings['LBL_POSTAL_CODE']}</td>
192
		<td scope='row'>${mod_strings['LBL_COUNTRY']}</td>
193
		</tr>
194
195
		<tr>
196
		<td ><input name='${prefix}primary_address_city'  maxlength='100' value='{$contact->primary_address_city}'></td>
197
		<td ><input name='${prefix}primary_address_state'  maxlength='100' value='{$contact->primary_address_state}'></td>
198
		<td ><input name='${prefix}primary_address_postalcode'  maxlength='100' value='{$contact->primary_address_postalcode}'></td>
199
		<td ><input name='${prefix}primary_address_country'  maxlength='100' value='{$contact->primary_address_country}'></td>
200
		</tr>
201
202
203
		<tr>
204
		<td nowrap scope='row'>$lbl_phone</td>
205
		<td nowrap scope='row'>${mod_strings['LBL_MOBILE_PHONE']}</td>
206
		<td nowrap scope='row'>${mod_strings['LBL_FAX_PHONE']}</td>
207
		<td nowrap scope='row'>${mod_strings['LBL_HOME_PHONE']}</td>
208
		</tr>
209
210
		<tr>
211
		<td nowrap ><input name='${prefix}phone_work' type="text" value="{$contact->phone_work}"></td>
212
		<td nowrap ><input name='${prefix}phone_mobile' type="text" value="{$contact->phone_mobile}"></td>
213
		<td nowrap ><input name='${prefix}phone_fax' type="text" value="{$contact->phone_fax}"></td>
214
		<td nowrap ><input name='${prefix}phone_home' type="text" value="{$contact->phone_home}"></td>
215
		</tr>
216
217
		<tr>
218
		<td scope='row' nowrap>${mod_strings['LBL_OTHER_PHONE']}</td>
219
		$lead_source_label
220
221
		<td scope="row">${mod_strings['LBL_BIRTHDATE']}&nbsp;</td>
222
		</tr>
223
224
225
		<tr>
226
		<td  nowrap><input name='${prefix}phone_other' type="text" value="{$contact->phone_other}"></td>
227
		$lead_source_field
228
229
		<td  nowrap>
230
			<input name='{$prefix}birthdate' onblur="parseDate(this, '$cal_dateformat');" size='12' maxlength='10' id='${prefix}jscal_field' type="text" value="{$birthdate}">&nbsp;
231
			<!--not_in_theme!--><img src="{$jsCalendarImage}" alt="{$app_strings['LBL_ENTER_DATE']}"  id="${prefix}jscal_trigger" align="absmiddle">
232
		</td>
233
		</tr>
234
235
EOQ;
236
237
$form .= $sugarEmailAddress->getEmailAddressWidgetEditView($contact->id, $_REQUEST['action']=='ConvertLead'?'Leads':'Contacts', false, 'include/SugarEmailAddress/templates/forWideFormBodyView.tpl');
238
239
require_once('include/SugarFields/Fields/Text/SugarFieldText.php');
240
$sugarfield = new SugarFieldText('Text');
241
$description_text = $sugarfield->getClassicEditView('description', $contact->description, $prefix, true);
242
243
$form .= <<<EOQ
244
		<tr>
245
		<td nowrap colspan='4' scope='row'>${mod_strings['LBL_DESCRIPTION']}</td>
246
		</tr>
247
		<tr>
248
		<td nowrap colspan='4' >{$description_text}</td>
249
		</tr>
250
EOQ;
251
252
253
254
	//carry forward custom lead fields common to contacts during Lead Conversion
255
    $tempContact = $this->getContact();
256
257
	if (method_exists($contact, 'convertCustomFieldsForm')) $contact->convertCustomFieldsForm($form, $tempContact, $prefix);
258
	unset($tempContact);
259
260
$form .= <<<EOQ
261
		</table>
262
263
		<input type='hidden' name='${prefix}alt_address_street'  value='{$contact->alt_address_street}'>
264
		<input type='hidden' name='${prefix}alt_address_city' value='{$contact->alt_address_city}'><input type='hidden' name='${prefix}alt_address_state'   value='{$contact->alt_address_state}'><input type='hidden' name='${prefix}alt_address_postalcode'   value='{$contact->alt_address_postalcode}'><input type='hidden' name='${prefix}alt_address_country'  value='{$contact->alt_address_country}'>
265
		<input type='hidden' name='${prefix}do_not_call'  value='{$contact->do_not_call}'>
266
		<input type='hidden' name='${prefix}email_opt_out'  value='{$contact->email_opt_out}'>
267
EOQ;
268
269
	if ($portal == true){
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
270
		if (isset($contact->portal_name)) {
271
			$form.="<input type='hidden' name='${prefix}portal_name'  value='{$contact->portal_name}'>";
272
		} else {
273
			$form.="<input type='hidden' name='${prefix}portal_name'  value=''>";
274
		}
275
		if (isset($contact->portal_app)) {
276
			$form.="<input type='hidden' name='${prefix}portal_app'  value='{$contact->portal_app}'>";
277
		} else {
278
			$form.="<input type='hidden' name='${prefix}portal_app'  value=''>";
279
		}
280
281
282
		if(!empty($contact->portal_name) && !empty($contact->portal_app)){
283
			$form .= "<input name='${prefix}portal_active' type='hidden' size='25'  value='1' >";
284
		}
285
286
	    if(isset($contact->portal_password)){
287
	        $form.="<input type='password' name='${prefix}portal_password1'  value='{$contact->portal_password}'>";
288
	        $form.="<input type='password' name='${prefix}portal_password'  value='{$contact->portal_password}'>";
289
	        $form .= "<input name='${prefix}old_portal_password' type='hidden' size='25'  value='{$contact->portal_password}' >";
290
	    }else{
291
	        $form.="<input type='password' name='${prefix}portal_password1'  value=''>";
292
	        $form.="<input type='password' name='${prefix}portal_password'  value=''>";
293
	        $form .= "<input name='${prefix}old_portal_password' type='hidden' size='25'  value='' >";
294
	    }
295
	}
296
297
$form .= <<<EOQ
298
			<script type="text/javascript">
299
				Calendar.setup ({
300
				inputField : "{$prefix}jscal_field", daFormat : "$cal_dateformat", ifFormat : "$cal_dateformat", showsTime : false, button : "{$prefix}jscal_trigger", singleClick : true, step : 1, weekNumbers:false
301
				});
302
			</script>
303
EOQ;
304
305
306
307
	$javascript = new javascript();
308
	$javascript->setFormName($formname);
309
	$javascript->setSugarBean($this->getContact());
310
	$javascript->addField('email1','false',$prefix);
311
	$javascript->addField('email2','false',$prefix);
312
	$javascript->addRequiredFields($prefix);
313
314
	$form .=$javascript->getScript();
315
	$mod_strings = $temp_strings;
316
317
318
	return $form;
319
}
320
321
function getFormBody($prefix, $mod='', $formname=''){
322
	if(!ACLController::checkAccess('Contacts', 'edit', true)){
323
		return '';
324
	}
325
global $mod_strings;
326
$temp_strings = $mod_strings;
327
if(!empty($mod)){
328
	global $current_language;
329
	$mod_strings = return_module_language($current_language, $mod);
330
}
331
		global $app_strings;
332
		global $current_user;
333
		$lbl_required_symbol = $app_strings['LBL_REQUIRED_SYMBOL'];
334
		$lbl_first_name = $mod_strings['LBL_FIRST_NAME'];
335
		$lbl_last_name = $mod_strings['LBL_LAST_NAME'];
336
		$lbl_phone = $mod_strings['LBL_PHONE'];
337
		$user_id = $current_user->id;
338
		$lbl_email_address = $mod_strings['LBL_EMAIL_ADDRESS'];
339
if ($formname == 'EmailEditView')
340
{
341
		$form = <<<EOQ
342
		<input type="hidden" name="${prefix}record" value="">
343
		<input type="hidden" name="${prefix}email2" value="">
344
		<input type="hidden" name="${prefix}phone_work" value="">
345
		<input type="hidden" name="${prefix}assigned_user_id" value='${user_id}'>
346
		$lbl_first_name<br>
347
		<input name="${prefix}first_name" type="text" value="" size=10><br>
348
		$lbl_last_name&nbsp;<span class="required">$lbl_required_symbol</span><br>
349
		<input name='${prefix}last_name' type="text" value="" size=10><br>
350
		$lbl_email_address&nbsp;<span class="required">$lbl_required_symbol</span><br>
351
		<input name='${prefix}email1' type="text" value=""><br><br>
352
353
EOQ;
354
}
355
else
356
{
357
		$form = <<<EOQ
358
		<input type="hidden" name="${prefix}record" value="">
359
		<input type="hidden" name="${prefix}email2" value="">
360
		<input type="hidden" name="${prefix}assigned_user_id" value='${user_id}'>
361
		$lbl_first_name<br>
362
		<input name="${prefix}first_name" type="text" value=""><br>
363
		$lbl_last_name&nbsp;<span class="required">$lbl_required_symbol</span><br>
364
		<input name='${prefix}last_name' type="text" value=""><br>
365
		$lbl_phone<br>
366
		<input name='${prefix}phone_work' type="text" value=""><br>
367
		$lbl_email_address<br>
368
		<input name='${prefix}email1' type="text" value=""><br><br>
369
370
EOQ;
371
}
372
373
374
$javascript = new javascript();
375
$javascript->setFormName($formname);
376
$javascript->setSugarBean($this->getContact());
377
$javascript->addField('email1','false',$prefix);
378
$javascript->addRequiredFields($prefix);
379
380
$form .=$javascript->getScript();
381
$mod_strings = $temp_strings;
382
return $form;
383
384
}
385
function getForm($prefix, $mod=''){
386
	if(!ACLController::checkAccess('Contacts', 'edit', true)){
387
		return '';
388
	}
389
if(!empty($mod)){
390
	global $current_language;
391
	$mod_strings = return_module_language($current_language, $mod);
392
}else global $mod_strings;
393
global $app_strings;
394
395
$lbl_save_button_title = $app_strings['LBL_SAVE_BUTTON_TITLE'];
396
$lbl_save_button_key = $app_strings['LBL_SAVE_BUTTON_KEY'];
397
$lbl_save_button_label = $app_strings['LBL_SAVE_BUTTON_LABEL'];
398
399
400
$the_form = get_left_form_header($mod_strings['LBL_NEW_FORM_TITLE']);
401
$the_form .= <<<EOQ
402
403
		<form name="${prefix}ContactSave" onSubmit="return check_form('${prefix}ContactSave')" method="POST" action="index.php">
404
			<input type="hidden" name="${prefix}module" value="Contacts">
405
			<input type="hidden" name="${prefix}action" value="Save">
406
EOQ;
407
$the_form .= $this->getFormBody($prefix,'Contacts', "${prefix}ContactSave");
408
$the_form .= <<<EOQ
409
		<input title="$lbl_save_button_title" accessKey="$lbl_save_button_key" class="button" type="submit" name="${prefix}button" value="  $lbl_save_button_label  " >
410
		</form>
411
412
EOQ;
413
$the_form .= get_left_form_footer();
414
$the_form .= get_validate_record_js();
415
416
return $the_form;
417
418
419
}
420
421
422
function handleSave($prefix, $redirect=true, $useRequired=false){
423
	global $theme, $current_user;
424
425
426
427
428
	require_once('include/formbase.php');
429
430
	global $timedate;
431
432
	$focus = $this->getContact();
433
434
	if($useRequired &&  !checkRequired($prefix, array_keys($focus->required_fields))){
435
		return null;
436
	}
437
438
	if (!empty($_POST[$prefix.'new_reports_to_id'])) {
439
		$focus->retrieve($_POST[$prefix.'new_reports_to_id']);
440
		$focus->reports_to_id = $_POST[$prefix.'record'];
441
	} else {
442
443
        $focus = populateFromPost($prefix, $focus);
444
        if( isset($_POST[$prefix.'old_portal_password']) && !empty($focus->portal_password) && $focus->portal_password != $_POST[$prefix.'old_portal_password']){
445
            $focus->portal_password = User::getPasswordHash($focus->portal_password);
446
        }
447
		if (!isset($_POST[$prefix.'email_opt_out'])) $focus->email_opt_out = 0;
448
		if (!isset($_POST[$prefix.'do_not_call'])) $focus->do_not_call = 0;
449
450
	}
451
	if(!$focus->ACLAccess('Save')){
452
			ACLController::displayNoAccess(true);
453
			sugar_cleanup(true);
454
	}
455
	if($_REQUEST['action'] != 'BusinessCard' && $_REQUEST['action'] != 'ConvertLead' && $_REQUEST['action'] != 'ConvertProspect')
456
	{
457
458
		if (!empty($_POST[$prefix.'sync_contact']) || !empty($focus->sync_contact)){
459
			 $focus->contacts_users_id = $current_user->id;
460
		}
461
		else{
462
			if (!isset($focus->users))
463
			{
464
	      	  	$focus->load_relationship('user_sync');
465
			}
466
	      	$focus->contacts_users_id = null;
467
			$focus->user_sync->delete($focus->id, $current_user->id);
468
		}
469
	}
470
471
	if (isset($GLOBALS['check_notify'])) {
472
		$check_notify = $GLOBALS['check_notify'];
473
	}
474
	else {
475
		$check_notify = FALSE;
476
	}
477
478
479
	if (empty($_POST['record']) && empty($_POST['dup_checked'])) {
480
481
		$duplicateContacts = $this->checkForDuplicates($prefix);
482
		if(isset($duplicateContacts)){
483
			$location='module=Contacts&action=ShowDuplicates';
484
			$get = '';
485
			if(isset($_POST['inbound_email_id']) && !empty($_POST['inbound_email_id'])) {
486
				$get .= '&inbound_email_id='.$_POST['inbound_email_id'];
487
			}
488
489
			// Bug 25311 - Add special handling for when the form specifies many-to-many relationships
490
			if(isset($_POST['relate_to']) && !empty($_POST['relate_to'])) {
491
				$get .= '&Contactsrelate_to='.$_POST['relate_to'];
492
			}
493
			if(isset($_POST['relate_id']) && !empty($_POST['relate_id'])) {
494
				$get .= '&Contactsrelate_id='.$_POST['relate_id'];
495
			}
496
497
			//add all of the post fields to redirect get string
498
			foreach ($focus->column_fields as $field)
499
			{
500
				if (!empty($focus->$field) && !is_object($focus->$field))
501
				{
502
					$get .= "&Contacts$field=".urlencode($focus->$field);
503
				}
504
			}
505
506
			foreach ($focus->additional_column_fields as $field)
507
			{
508
				if (!empty($focus->$field))
509
				{
510
					$get .= "&Contacts$field=".urlencode($focus->$field);
511
				}
512
			}
513
514
			if($focus->hasCustomFields()) {
515
				foreach($focus->field_defs as $name=>$field) {
516
					if (!empty($field['source']) && $field['source'] == 'custom_fields')
517
					{
518
						$get .= "&Contacts$name=".urlencode($focus->$name);
519
					}
520
				}
521
			}
522
523
524
			$emailAddress = new SugarEmailAddress();
525
			$get .= $emailAddress->getFormBaseURL($focus);
526
527
528
			//create list of suspected duplicate contact id's in redirect get string
529
			$i=0;
530
			foreach ($duplicateContacts as $contact)
531
			{
532
				$get .= "&duplicate[$i]=".$contact['id'];
533
				$i++;
534
			}
535
536
			//add return_module, return_action, and return_id to redirect get string
537
			$urlData = array('return_module' => 'Contacts', 'return_action' => '');
538
			foreach (array('return_module', 'return_action', 'return_id', 'popup', 'create', 'start') as $var) {
539
			    if (!empty($_POST[$var])) {
540
			        $urlData[$var] = $_POST[$var];
541
			    }
542
			}
543
			$get .= "&".http_build_query($urlData);
544
			$_SESSION['SHOW_DUPLICATES'] = $get;
545
546
            //now redirect the post to modules/Contacts/ShowDuplicates.php
547
            if (!empty($_POST['is_ajax_call']) && $_POST['is_ajax_call'] == '1')
548
            {
549
            	ob_clean();
550
                $json = getJSONobj();
551
                echo $json->encode(array('status' => 'dupe', 'get' => $location));
552
            }
553
            else if(!empty($_REQUEST['ajax_load']))
554
            {
555
                echo "<script>SUGAR.ajaxUI.loadContent('index.php?$location');</script>";
556
            }
557
            else {
558
                if(!empty($_POST['to_pdf'])) $location .= '&to_pdf='.urlencode($_POST['to_pdf']);
559
                header("Location: index.php?$location");
560
            }
561
            return null;
562
		}
563
	}
564
565
	global $current_user;
566
	if(is_admin($current_user)){
567
		if (!isset($_POST[$prefix.'portal_active'])) $focus->portal_active = '0';
568
		//if no password is set set account to inactive for portal
569
		if(empty($_POST[$prefix.'portal_name']))$focus->portal_active = '0';
570
571
	}
572
573
	///////////////////////////////////////////////////////////////////////////////
574
	////	INBOUND EMAIL HANDLING
575
	///////////////////////////////////////////////////////////////////////////////
576
	if(isset($_REQUEST['inbound_email_id']) && !empty($_REQUEST['inbound_email_id'])) {
577
		// fake this case like it's already saved.
578
		$focus->save($check_notify);
579
580
		$email = new Email();
581
		$email->retrieve($_REQUEST['inbound_email_id']);
582
		$email->parent_type = 'Contacts';
583
		$email->parent_id = $focus->id;
584
		$email->assigned_user_id = $current_user->id;
585
		$email->status = 'read';
586
		$email->save();
587
		$email->load_relationship('contacts');
588
		$email->contacts->add($focus->id);
589
590
		header("Location: index.php?&module=Emails&action=EditView&type=out&inbound_email_id=".$_REQUEST['inbound_email_id']."&parent_id=".$email->parent_id."&parent_type=".$email->parent_type.'&start='.$_REQUEST['start'].'&assigned_user_id='.$current_user->id);
591
		exit();
592
	}
593
	////	END INBOUND EMAIL HANDLING
594
	///////////////////////////////////////////////////////////////////////////////
595
596
	$focus->save($check_notify);
597
	$return_id = $focus->id;
598
599
	$GLOBALS['log']->debug("Saved record with id of ".$return_id);
600
601
    if ($redirect && !empty($_POST['is_ajax_call']) && $_POST['is_ajax_call'] == '1') {
602
        $json = getJSONobj();
603
        echo $json->encode(array('status' => 'success',
604
                                 'get' => ''));
605
    	$trackerManager = TrackerManager::getInstance();
606
        $timeStamp = TimeDate::getInstance()->nowDb();
607
        if($monitor = $trackerManager->getMonitor('tracker')){
608
	        $monitor->setValue('action', 'detailview');
609
	        $monitor->setValue('user_id', $GLOBALS['current_user']->id);
610
	        $monitor->setValue('module_name', 'Contacts');
611
	        $monitor->setValue('date_modified', $timeStamp);
612
	        $monitor->setValue('visible', 1);
613
614
	        if (!empty($this->bean->id)) {
615
	            $monitor->setValue('item_id', $return_id);
616
	            $monitor->setValue('item_summary', $focus->get_summary_text());
617
	        }
618
			$trackerManager->saveMonitor($monitor, true, true);
619
		}
620
        return null;
621
    }
622
623
	if($redirect && isset($_POST['popup']) && $_POST['popup'] == 'true') {
624
	    $urlData = array("query" => true, "first_name" => $focus->first_name, "last_name" => $focus->last_name,
625
	       "module" => 'Accounts', 'action' => 'Popup');
626
    	if (!empty($_POST['return_module'])) {
627
    	    $urlData['module'] = $_POST['return_module'];
628
    	}
629
        if (!empty($_POST['return_action'])) {
630
    	    $urlData['action'] = $_POST['return_action'];
631
    	}
632
    	foreach(array('return_id', 'popup', 'create', 'to_pdf') as $var) {
633
    	    if (!empty($_POST[$var])) {
634
    	        $urlData[$var] = $_POST[$var];
635
    	    }
636
    	}
637
		header("Location: index.php?".http_build_query($urlData));
638
		return;
639
	}
640
641
	if($redirect){
642
		$this->handleRedirect($return_id);
643
	}else{
644
		return $focus;
645
	}
646
}
647
648
function handleRedirect($return_id){
649
	if(isset($_POST['return_module']) && $_POST['return_module'] != "") {
650
		$return_module = urlencode($_POST['return_module']);
651
	}
652
	else {
653
		$return_module = "Contacts";
654
	}
655
656
	if(isset($_POST['return_action']) && $_POST['return_action'] != "") {
657
		if($_REQUEST['return_module'] == 'Emails') {
658
			$return_action = urlencode($_REQUEST['return_action']);
659
		}
660
		// if we create a new record "Save", we want to redirect to the DetailView
661
		elseif($_REQUEST['action'] == "Save" && $_REQUEST['return_module'] != "Home") {
662
			$return_action = 'DetailView';
663
		} else {
664
			// if we "Cancel", we go back to the list view.
665
			$return_action = urlencode($_REQUEST['return_action']);
666
		}
667
	}
668
	else {
669
		$return_action = "DetailView";
670
	}
671
672
	if(isset($_POST['return_id']) && $_POST['return_id'] != "") {
673
        $return_id = urlencode($_POST['return_id']);
674
	}
675
676
	//eggsurplus Bug 23816: maintain VCR after an edit/save. If it is a duplicate then don't worry about it. The offset is now worthless.
677
 	$redirect_url = "index.php?action=$return_action&module=$return_module&record=$return_id";
678
 	if(isset($_REQUEST['offset']) && empty($_REQUEST['duplicateSave'])) {
679
 	    $redirect_url .= "&offset=".$_REQUEST['offset'];
680
 	}
681
682
    if(!empty($_REQUEST['ajax_load'])){
683
        echo "<script>SUGAR.ajaxUI.loadContent('$redirect_url');</script>\n";
684
    }
685
    else {
686
        header("Location: ". $redirect_url);
687
    }
688
}
689
690
    /**
691
    * @return Contact
692
    */
693
    protected function getContact()
694
    {
695
        return new Contact();
696
    }
697
}
698
699