Test Failed
Push — CI ( 0f01dd...c95a04 )
by Adam
55:13
created

User   F

Complexity

Total Complexity 257

Size/Duplication

Total Lines 1818
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12
Metric Value
wmc 257
lcom 1
cbo 12
dl 0
loc 1818
rs 3.4838

68 Methods

Rating   Name   Duplication   Size   Complexity  
A User() 0 5 1
A _loadUserPreferencesFocus() 0 4 1
A getSystemUser() 0 11 2
A getDefaultSignature() 0 7 2
A getSignature() 0 6 2
A getSignaturesArray() 0 13 2
B getSignatures() 0 25 6
A getSignatureButtons() 0 15 3
A hasPersonalEmail() 0 7 1
A getUserPrivGuid() 0 15 3
A setUserPrivGuid() 0 5 1
A setPreference() 0 17 2
A resetPreferences() 0 14 2
A savePreferencesToDB() 0 12 2
A reloadPreferences() 0 4 1
A getUserDateTimePreferences() 0 12 2
A loadPreferences() 0 14 2
A getPreference() 0 15 2
A incrementETag() 0 8 2
A getETagSeed() 0 7 2
A getLicensedUsersWhere() 0 5 1
C save() 0 42 8
C check_role_membership() 0 41 8
A get_summary_text() 0 4 1
A encrypt_password() 0 8 1
A retrieve() 0 9 3
A retrieve_by_email_address() 0 19 2
A bean_implements() 0 6 2
B getPasswordHash() 0 14 5
A checkPassword() 0 4 1
A checkPasswordMD5() 0 9 4
A findUserPassword() 0 17 4
A setNewPassword() 0 13 1
A is_authenticated() 0 3 1
A fill_in_additional_list_fields() 0 3 1
A fill_in_additional_detail_fields() 0 20 2
A retrieve_user_id() 0 11 2
C verify_data() 0 62 13
C get_list_view_data() 0 32 8
A list_view_parse_additional_sections() 0 3 1
A getAllUsers() 0 8 1
A getActiveUsers() 0 6 1
B create_export_query() 0 31 6
A get_meetings() 0 5 1
A get_calls() 0 5 1
C displayEmailCounts() 0 54 11
A getPreferredEmail() 0 15 2
A getUsersNameAndEmail() 0 13 2
A getSystemDefaultNameAndEmail() 0 8 1
A setDefaultsInConfig() 0 8 1
C getEmailInfo() 0 33 8
C getEmailLink2() 0 64 8
C getEmailLink() 0 66 9
B getLocaleFormatDesc() 0 30 3
A _fixupModuleForACL() 0 10 3
C _getModulesForACL() 0 44 8
A isAdmin() 0 7 4
A isDeveloperForAnyModule() 0 10 3
A getDeveloperModules() 0 8 2
A isDeveloperForModule() 0 19 4
A getAdminModules() 0 7 2
A isAdminForModule() 0 19 4
A showLastNameFirst() 0 9 2
B create_new_list_query() 0 57 7
A get_first_day_of_week() 0 10 2
D sendEmailForPassword() 0 123 16
B afterImportSave() 0 21 6
A isPrimaryEmail() 0 8 4

How to fix   Complexity   

Complex Class

Complex classes like User often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use User, and based on these observations, apply Extract Interface, too.

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
require_once('include/SugarObjects/templates/person/Person.php');
42
43
// User is used to store customer information.
44
class User extends Person {
45
	// Stored fields
46
	var $name = '';
47
	var $full_name;
48
	var $id;
49
	var $user_name;
50
	var $user_hash;
51
	var $salutation;
52
	var $first_name;
53
	var $last_name;
54
	var $date_entered;
55
	var $date_modified;
56
	var $modified_user_id;
57
	var $created_by;
58
	var $created_by_name;
59
	var $modified_by_name;
60
	var $description;
61
	var $phone_home;
62
	var $phone_mobile;
63
	var $phone_work;
64
	var $phone_other;
65
	var $phone_fax;
66
	var $email1;
67
	var $email2;
68
	var $address_street;
69
	var $address_city;
70
	var $address_state;
71
	var $address_postalcode;
72
	var $address_country;
73
	var $status;
74
	var $title;
75
    var $photo;
76
	var $portal_only;
77
	var $department;
78
	var $authenticated = false;
79
	var $error_string;
80
	var $is_admin;
81
	var $employee_status;
82
	var $messenger_id;
83
	var $messenger_type;
84
	var $is_group;
85
	var $accept_status; // to support Meetings
86
	//adding a property called team_id so we can populate it for use in the team widget
87
	var $team_id;
88
89
	var $receive_notifications;
90
91
	var $reports_to_name;
92
	var $reports_to_id;
93
	var $team_exists = false;
94
	var $table_name = "users";
95
	var $module_dir = 'Users';
96
	var $object_name = "User";
97
	var $user_preferences;
98
99
	var $importable = true;
100
	var $_userPreferenceFocus;
101
102
	var $encodeFields = Array ("first_name", "last_name", "description");
103
104
	// This is used to retrieve related fields from form posts.
105
	var $additional_column_fields = array ('reports_to_name'
106
	);
107
108
	var $emailAddress;
109
110
111
	var $new_schema = true;
112
113
	function User() {
114
		parent::Person();
115
116
		$this->_loadUserPreferencesFocus();
117
	}
118
119
	protected function _loadUserPreferencesFocus()
120
	{
121
	    $this->_userPreferenceFocus = new UserPreference($this);
122
	}
123
124
    /**
125
     * returns an admin user
126
     */
127
    public function getSystemUser()
128
    {
129
        if (null === $this->retrieve('1'))
130
            // handle cases where someone deleted user with id "1"
131
            $this->retrieve_by_string_fields(array(
132
                'status' => 'Active',
133
                'is_admin' => '1',
134
                ));
135
136
        return $this;
137
    }
138
139
140
	/**
141
	 * convenience function to get user's default signature
142
	 */
143
	function getDefaultSignature() {
144
		if($defaultId = $this->getPreference('signature_default')) {
145
			return $this->getSignature($defaultId);
146
		} else {
147
			return array();
148
		}
149
	}
150
151
	/**
152
	 * retrieves the signatures for a user
153
	 * @param string id ID of user_signature
154
	 * @return array ID, signature, and signature_html
155
	 */
156
	public function getSignature($id)
157
	{
158
	    $signatures = $this->getSignaturesArray();
159
160
	    return isset($signatures[$id]) ? $signatures[$id] : FALSE;
161
	}
162
163
	function getSignaturesArray() {
164
		$q = 'SELECT * FROM users_signatures WHERE user_id = \''.$this->id.'\' AND deleted = 0 ORDER BY name ASC';
165
		$r = $this->db->query($q);
166
167
		// provide "none"
168
		$sig = array(""=>"");
169
170
		while($a = $this->db->fetchByAssoc($r)) {
171
			$sig[$a['id']] = $a;
172
		}
173
174
		return $sig;
175
	}
176
177
	/**
178
	 * retrieves any signatures that the User may have created as <select>
179
	 */
180
	public function getSignatures(
181
	    $live = false,
182
	    $defaultSig = '',
183
	    $forSettings = false
184
	    )
185
	{
186
		$sig = $this->getSignaturesArray();
187
		$sigs = array();
188
		foreach ($sig as $key => $arr)
189
		{
190
			$sigs[$key] = !empty($arr['name']) ? $arr['name'] : '';
191
		}
192
193
		$change = '';
194
		if(!$live) {
195
			$change = ($forSettings) ? "onChange='displaySignatureEdit();'" : "onChange='setSigEditButtonVisibility();'";
196
		}
197
198
		$id = (!$forSettings) ? 'signature_id' : 'signature_idDisplay';
199
200
		$out  = "<select {$change} id='{$id}' name='{$id}'>";
201
		$out .= get_select_options_with_id($sigs, $defaultSig).'</select>';
202
203
		return $out;
204
	}
205
206
	/**
207
	 * returns buttons and JS for signatures
208
	 */
209
	function getSignatureButtons($jscall='', $defaultDisplay=false) {
210
		global $mod_strings;
211
212
		$jscall = empty($jscall) ? 'open_email_signature_form' : $jscall;
213
214
		$butts  = "<input class='button' onclick='javascript:{$jscall}(\"\", \"{$this->id}\");' value='{$mod_strings['LBL_BUTTON_CREATE']}' type='button'>&nbsp;";
215
		if($defaultDisplay) {
216
			$butts .= '<span name="edit_sig" id="edit_sig" style="visibility:inherit;"><input class="button" onclick="javascript:'.$jscall.'(document.getElementById(\'signature_id\', \'\').value)" value="'.$mod_strings['LBL_BUTTON_EDIT'].'" type="button" tabindex="392">&nbsp;
217
					</span>';
218
		} else {
219
			$butts .= '<span name="edit_sig" id="edit_sig" style="visibility:hidden;"><input class="button" onclick="javascript:'.$jscall.'(document.getElementById(\'signature_id\', \'\').value)" value="'.$mod_strings['LBL_BUTTON_EDIT'].'" type="button" tabindex="392">&nbsp;
220
					</span>';
221
		}
222
		return $butts;
223
	}
224
225
	/**
226
	 * performs a rudimentary check to verify if a given user has setup personal
227
	 * InboundEmail
228
	 *
229
	 * @return bool
230
	 */
231
	public function hasPersonalEmail()
232
	{
233
	    $focus = new InboundEmail;
234
	    $focus->retrieve_by_string_fields(array('group_id' => $this->id));
235
236
	    return !empty($focus->id);
237
	}
238
239
	/* Returns the User's private GUID; this is unassociated with the User's
240
	 * actual GUID.  It is used to secure file names that must be HTTP://
241
	 * accesible, but obfusicated.
242
	 */
243
	function getUserPrivGuid() {
244
        $userPrivGuid = $this->getPreference('userPrivGuid', 'global', $this);
245
		if ($userPrivGuid) {
246
			return $userPrivGuid;
247
		} else {
248
			$this->setUserPrivGuid();
249
			if (!isset ($_SESSION['setPrivGuid'])) {
250
				$_SESSION['setPrivGuid'] = true;
251
				$userPrivGuid = $this->getUserPrivGuid();
252
				return $userPrivGuid;
253
			} else {
254
				sugar_die("Breaking Infinite Loop Condition: Could not setUserPrivGuid.");
255
			}
256
		}
257
	}
258
259
	function setUserPrivGuid() {
260
		$privGuid = create_guid();
261
		//($name, $value, $nosession=0)
262
		$this->setPreference('userPrivGuid', $privGuid, 0, 'global', $this);
263
	}
264
265
	/**
266
	 * Interface for the User object to calling the UserPreference::setPreference() method in modules/UserPreferences/UserPreference.php
267
	 *
268
	 * @see UserPreference::setPreference()
269
	 *
270
	 * @param string $name Name of the preference to set
271
	 * @param string $value Value to set preference to
272
	 * @param null $nosession For BC, ignored
273
	 * @param string $category Name of the category to retrieve
274
	 */
275
	public function setPreference(
276
	    $name,
277
	    $value,
278
	    $nosession = 0,
279
	    $category = 'global'
280
	    )
281
	{
282
	    // for BC
283
	    if ( func_num_args() > 4 ) {
284
	        $user = func_get_arg(4);
285
	        $GLOBALS['log']->deprecated('User::setPreferences() should not be used statically.');
286
	    }
287
	    else
288
	        $user = $this;
289
290
        $user->_userPreferenceFocus->setPreference($name, $value, $category);
291
	}
292
293
	/**
294
	 * Interface for the User object to calling the UserPreference::resetPreferences() method in modules/UserPreferences/UserPreference.php
295
	 *
296
	 * @see UserPreference::resetPreferences()
297
	 *
298
	 * @param string $category category to reset
299
	 */
300
	public function resetPreferences(
301
	    $category = null
302
	    )
303
	{
304
	    // for BC
305
	    if ( func_num_args() > 1 ) {
306
	        $user = func_get_arg(1);
307
	        $GLOBALS['log']->deprecated('User::resetPreferences() should not be used statically.');
308
	    }
309
	    else
310
	        $user = $this;
311
312
        $user->_userPreferenceFocus->resetPreferences($category);
313
	}
314
315
	/**
316
	 * Interface for the User object to calling the UserPreference::savePreferencesToDB() method in modules/UserPreferences/UserPreference.php
317
	 *
318
	 * @see UserPreference::savePreferencesToDB()
319
	 */
320
	public function savePreferencesToDB()
321
	{
322
        // for BC
323
	    if ( func_num_args() > 0 ) {
324
	        $user = func_get_arg(0);
325
	        $GLOBALS['log']->deprecated('User::savePreferencesToDB() should not be used statically.');
326
	    }
327
	    else
328
	        $user = $this;
329
330
        $user->_userPreferenceFocus->savePreferencesToDB();
331
	}
332
333
	/**
334
	 * Unconditionally reloads user preferences from the DB and updates the session
335
	 * @param string $category name of the category to retreive, defaults to global scope
336
	 * @return bool successful?
337
	 */
338
	public function reloadPreferences($category = 'global')
339
	{
340
	    return $this->_userPreferenceFocus->reloadPreferences($category = 'global');
341
	}
342
343
	/**
344
	 * Interface for the User object to calling the UserPreference::getUserDateTimePreferences() method in modules/UserPreferences/UserPreference.php
345
	 *
346
	 * @see UserPreference::getUserDateTimePreferences()
347
	 *
348
	 * @return array 'date' - date format for user ; 'time' - time format for user
349
	 */
350
	public function getUserDateTimePreferences()
351
	{
352
        // for BC
353
	    if ( func_num_args() > 0 ) {
354
	        $user = func_get_arg(0);
355
	        $GLOBALS['log']->deprecated('User::getUserDateTimePreferences() should not be used statically.');
356
	    }
357
	    else
358
	        $user = $this;
359
360
        return $user->_userPreferenceFocus->getUserDateTimePreferences();
361
	}
362
363
	/**
364
	 * Interface for the User object to calling the UserPreference::loadPreferences() method in modules/UserPreferences/UserPreference.php
365
	 *
366
	 * @see UserPreference::loadPreferences()
367
	 *
368
	 * @param string $category name of the category to retreive, defaults to global scope
369
	 * @return bool successful?
370
	 */
371
	public function loadPreferences(
372
	    $category = 'global'
373
	    )
374
	{
375
	    // for BC
376
	    if ( func_num_args() > 1 ) {
377
	        $user = func_get_arg(1);
378
	        $GLOBALS['log']->deprecated('User::loadPreferences() should not be used statically.');
379
	    }
380
	    else
381
	        $user = $this;
382
383
        return $user->_userPreferenceFocus->loadPreferences($category);
384
	}
385
386
	/**
387
	 * Interface for the User object to calling the UserPreference::setPreference() method in modules/UserPreferences/UserPreference.php
388
	 *
389
	 * @see UserPreference::getPreference()
390
	 *
391
	 * @param string $name name of the preference to retreive
392
	 * @param string $category name of the category to retreive, defaults to global scope
393
	 * @return mixed the value of the preference (string, array, int etc)
394
	 */
395
	public function getPreference(
396
	    $name,
397
	    $category = 'global'
398
	    )
399
	{
400
	    // for BC
401
	    if ( func_num_args() > 2 ) {
402
	        $user = func_get_arg(2);
403
	        $GLOBALS['log']->deprecated('User::getPreference() should not be used statically.');
404
	    }
405
	    else
406
	        $user = $this;
407
408
        return $user->_userPreferenceFocus->getPreference($name, $category);
409
	}
410
411
	/**
412
     * incrementETag
413
     *
414
     * This function increments any ETag seed needed for a particular user's
415
     * UI. For example, if the user changes their theme, the ETag seed for the
416
     * main menu needs to be updated, so you call this function with the seed name
417
     * to do so:
418
     *
419
     * UserPreference::incrementETag("mainMenuETag");
420
     *
421
     * @param string $tag ETag seed name.
422
     * @return nothing
423
     */
424
    public function incrementETag($tag){
425
    	$val = $this->getETagSeed($tag);
426
    	if($val == 2147483648){
427
    		$val = 0;
428
    	}
429
    	$val++;
430
    	$this->setPreference($tag, $val, 0, "ETag");
431
    }
432
433
    /**
434
     * getETagSeed
435
     *
436
     * This function is a wrapper to encapsulate getting the ETag seed and
437
     * making sure it's sanitized for use in the app.
438
     *
439
     * @param string $tag ETag seed name.
440
     * @return integer numeric value of the seed
441
     */
442
    public function getETagSeed($tag){
443
    	$val = $this->getPreference($tag, "ETag");
444
    	if($val == null){
445
    		$val = 0;
446
    	}
447
    	return $val;
448
    }
449
450
451
   /**
452
    * Get WHERE clause that fetches all users counted for licensing purposes
453
    * @return string
454
    */
455
	public static function getLicensedUsersWhere()
456
	{
457
		return "deleted=0 AND status='Active' AND user_name IS NOT NULL AND is_group=0 AND portal_only=0  AND ".$GLOBALS['db']->convert('user_name', 'length').">0";
458
	    return "1<>1";
0 ignored issues
show
Unused Code introduced by
return '1<>1'; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
459
	}
460
461
	function save($check_notify = false) {
462
		$isUpdate = !empty($this->id) && !$this->new_with_id;
463
464
465
		$query = "SELECT count(id) as total from users WHERE ".self::getLicensedUsersWhere();
466
467
468
        // is_group & portal should be set to 0 by default
469
        if (!isset($this->is_group)) {
470
            $this->is_group = 0;
471
        }
472
        if (!isset($this->portal_only)) {
473
            $this->portal_only = 0;
474
        }
475
476
        // wp: do not save user_preferences in this table, see user_preferences module
477
		$this->user_preferences = '';
478
479
		// if this is an admin user, do not allow is_group or portal_only flag to be set.
480
		if ($this->is_admin) {
481
			$this->is_group = 0;
482
			$this->portal_only = 0;
483
		}
484
485
486
		// set some default preferences when creating a new user
487
		$setNewUserPreferences = empty($this->id) || !empty($this->new_with_id);
488
489
490
		parent::save($check_notify);
491
492
493
		// set some default preferences when creating a new user
494
		if ( $setNewUserPreferences ) {
495
	        if(!$this->getPreference('calendar_publish_key')) {
496
		        $this->setPreference('calendar_publish_key', create_guid());
497
	        }
498
		}
499
500
        $this->savePreferencesToDB();
501
        return $this->id;
502
	}
503
504
	/**
505
	* @return boolean true if the user is a member of the role_name, false otherwise
506
	* @param string $role_name - Must be the exact name of the acl_role
507
	* @param string $user_id - The user id to check for the role membership, empty string if current user
508
	* @desc Determine whether or not a user is a member of an ACL Role. This function caches the
509
	*       results in the session or to prevent running queries after the first time executed.
510
	* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
511
	* All Rights Reserved..
512
	* Contributor(s): ______________________________________..
513
	*/
514
	function check_role_membership($role_name, $user_id = ''){
515
516
		global $current_user;
517
518
		if(empty($user_id))
519
			$user_id = $current_user->id;
520
521
		// Check the Sugar External Cache to see if this users memberships were cached
522
		$role_array = sugar_cache_retrieve("RoleMemberships_".$user_id);
523
524
		// If we are pulling the roles for the current user
525
		if($user_id == $current_user->id){
526
			// If the Session doesn't contain the values
527
			if(!isset($_SESSION['role_memberships'])){
528
				// This means the external cache already had it loaded
529
				if(!empty($role_array))
530
					$_SESSION['role_memberships'] = $role_array;
531
				else{
532
					$_SESSION['role_memberships'] = ACLRole::getUserRoleNames($user_id);
533
					$role_array = $_SESSION['role_memberships'];
534
				}
535
			}
536
			// else the session had the values, so we assign to the role array
537
			else{
538
				$role_array = $_SESSION['role_memberships'];
539
			}
540
		}
541
		else{
542
			// If the external cache didn't contain the values, we get them and put them in cache
543
			if(!$role_array){
544
				$role_array = ACLRole::getUserRoleNames($user_id);
545
				sugar_cache_put("RoleMemberships_".$user_id, $role_array);
0 ignored issues
show
Bug introduced by
It seems like $role_array defined by \ACLRole::getUserRoleNames($user_id) on line 544 can also be of type array; however, sugar_cache_put() does only seem to accept object<Serializable>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
546
			}
547
		}
548
549
		// If the role doesn't exist in the list of the user's roles
550
		if(!empty($role_array) && in_array($role_name, $role_array))
551
			return true;
552
		else
553
			return false;
554
	}
555
556
    function get_summary_text() {
557
        //$this->_create_proper_name_field();
558
        return $this->name;
559
	}
560
561
	/**
562
	 * @deprecated
563
	* @param string $user_name - Must be non null and at least 2 characters
0 ignored issues
show
Bug introduced by
There is no parameter named $user_name. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
564
	* @param string $user_password - Must be non null and at least 1 character.
565
	* @desc Take an unencrypted username and password and return the encrypted password
566
	* @return string encrypted password for storage in DB and comparison against DB password.
567
	*/
568
	function encrypt_password($user_password)
569
	{
570
		// encrypt the password.
571
		$salt = substr($this->user_name, 0, 2);
572
		$encrypted_password = crypt($user_password, $salt);
573
574
		return $encrypted_password;
575
	}
576
577
	/**
578
	 * Authenicates the user; returns true if successful
579
	 *
580
	 * @param string $password MD5-encoded password
581
	 * @return bool
582
	 */
583
	public function authenticate_user($password)
584
	{
585
	    $row = self::findUserPassword($this->user_name, $password);
586
	    if(empty($row)) {
587
	        return false;
588
		} else {
589
			$this->id = $row['id'];
590
			return true;
591
		}
592
	}
593
594
    /**
595
     * retrieves an User bean
596
     * preformat name & full_name attribute with first/last
597
     * loads User's preferences
598
     *
599
     * @param string id ID of the User
600
     * @param bool encode encode the result
601
     * @return object User bean
602
     * @return null null if no User found
603
     */
604
	function retrieve($id = -1, $encode = true, $deleted = true) {
605
		$ret = parent::retrieve($id, $encode, $deleted);
606
		if ($ret) {
607
			if (isset ($_SESSION)) {
608
				$this->loadPreferences();
609
			}
610
		}
611
		return $ret;
612
	}
613
614
	function retrieve_by_email_address($email) {
615
616
		$email1= strtoupper($email);
617
		$q=<<<EOQ
618
619
		select id from users where id in ( SELECT  er.bean_id AS id FROM email_addr_bean_rel er,
620
			email_addresses ea WHERE ea.id = er.email_address_id
621
		    AND ea.deleted = 0 AND er.deleted = 0 AND er.bean_module = 'Users' AND email_address_caps IN ('{$email1}') )
622
EOQ;
623
624
625
		$res=$this->db->query($q);
626
		$row=$this->db->fetchByAssoc($res);
627
628
		if (!empty($row['id'])) {
629
			return $this->retrieve($row['id']);
630
		}
631
		return '';
632
	}
633
634
   function bean_implements($interface) {
635
        switch($interface){
636
            case 'ACL':return true;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
637
        }
638
        return false;
639
    }
640
641
642
	/**
643
	 * Load a user based on the user_name in $this
644
	 * @param string $user_password Password
645
	 * @param bool $password_encoded Is password md5-encoded or plain text?
646
	 * @return -- this if load was successul and null if load failed.
0 ignored issues
show
Documentation introduced by
The doc-type -- could not be parsed: Unknown type name "--" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
647
	 */
648
	function load_user($user_password, $password_encoded = false)
649
	{
650
		global $login_error;
651
		unset($GLOBALS['login_error']);
652
		if(isset ($_SESSION['loginattempts'])) {
653
			$_SESSION['loginattempts'] += 1;
654
		} else {
655
			$_SESSION['loginattempts'] = 1;
656
		}
657
		if($_SESSION['loginattempts'] > 5) {
658
			$GLOBALS['log']->fatal('SECURITY: '.$this->user_name.' has attempted to login '.$_SESSION['loginattempts'].' times from IP address: '.$_SERVER['REMOTE_ADDR'].'.');
659
			return null;
660
		}
661
662
		$GLOBALS['log']->debug("Starting user load for $this->user_name");
663
664
		if (!isset ($this->user_name) || $this->user_name == "" || !isset ($user_password) || $user_password == "")
665
			return null;
666
667
	    if(!$password_encoded) {
668
	        $user_password = md5($user_password);
669
	    }
670
        $row = self::findUserPassword($this->user_name, $user_password);
671
		if(empty($row) || !empty ($GLOBALS['login_error'])) {
672
			$GLOBALS['log']->fatal('SECURITY: User authentication for '.$this->user_name.' failed - could not Load User from Database');
673
			return null;
674
		}
675
676
		// now fill in the fields.
677
		$this->loadFromRow($row);
678
		$this->loadPreferences();
679
680
		require_once ('modules/Versions/CheckVersions.php');
681
		$invalid_versions = get_invalid_versions();
682
683
		if (!empty ($invalid_versions)) {
684
			if (isset ($invalid_versions['Rebuild Relationships'])) {
685
				unset ($invalid_versions['Rebuild Relationships']);
686
687
				// flag for pickup in DisplayWarnings.php
688
				$_SESSION['rebuild_relationships'] = true;
689
			}
690
691
			if (isset ($invalid_versions['Rebuild Extensions'])) {
692
				unset ($invalid_versions['Rebuild Extensions']);
693
694
				// flag for pickup in DisplayWarnings.php
695
				$_SESSION['rebuild_extensions'] = true;
696
			}
697
698
			$_SESSION['invalid_versions'] = $invalid_versions;
699
		}
700
		if ($this->status != "Inactive")
701
			$this->authenticated = true;
702
703
		unset ($_SESSION['loginattempts']);
704
		return $this;
705
	}
706
707
	/**
708
	 * Generate a new hash from plaintext password
709
	 * @param string $password
710
	 */
711
	public static function getPasswordHash($password)
712
	{
713
	    if(!defined('CRYPT_MD5') || !constant('CRYPT_MD5')) {
714
	        // does not support MD5 crypt - leave as is
715
	        if(defined('CRYPT_EXT_DES') && constant('CRYPT_EXT_DES')) {
716
	            return crypt(strtolower(md5($password)),
717
	            	"_.012".substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), -4));
718
	        }
719
	        // plain crypt cuts password to 8 chars, which is not enough
720
	        // fall back to old md5
721
	        return strtolower(md5($password));
722
	    }
723
	    return crypt(strtolower(md5($password)));
724
	}
725
726
	/**
727
	 * Check that password matches existing hash
728
	 * @param string $password Plaintext password
729
	 * @param string $user_hash DB hash
730
	 */
731
	public static function checkPassword($password, $user_hash)
732
	{
733
	    return self::checkPasswordMD5(md5($password), $user_hash);
734
	}
735
736
	/**
737
	 * Check that md5-encoded password matches existing hash
738
	 * @param string $password MD5-encoded password
0 ignored issues
show
Documentation introduced by
There is no parameter named $password. Did you maybe mean $password_md5?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
739
	 * @param string $user_hash DB hash
740
	 * @return bool Match or not?
741
	 */
742
	public static function checkPasswordMD5($password_md5, $user_hash)
743
	{
744
	    if(empty($user_hash)) return false;
745
	    if($user_hash[0] != '$' && strlen($user_hash) == 32) {
746
	        // Old way - just md5 password
747
	        return strtolower($password_md5) == $user_hash;
748
	    }
749
	    return crypt(strtolower($password_md5), $user_hash) == $user_hash;
750
	}
751
752
	/**
753
	 * Find user with matching password
754
	 * @param string $name Username
755
	 * @param string $password MD5-encoded password
756
	 * @param string $where Limiting query
757
	 * @return the matching User of false if not found
758
	 */
759
	public static function findUserPassword($name, $password, $where = '')
760
	{
761
	    global $db;
762
		$name = $db->quote($name);
763
		$query = "SELECT * from users where user_name='$name'";
764
		if(!empty($where)) {
765
		    $query .= " AND $where";
766
		}
767
		$result = $db->limitQuery($query,0,1,false);
768
		if(!empty($result)) {
769
		    $row = $db->fetchByAssoc($result);
770
		    if(self::checkPasswordMD5($password, $row['user_hash'])) {
771
		        return $row;
772
		    }
773
		}
774
		return false;
775
	}
776
777
	/**
778
	 * Sets new password and resets password expiration timers
779
	 * @param string $new_password
780
	 */
781
	public function setNewPassword($new_password, $system_generated = '0')
782
	{
783
        $user_hash = self::getPasswordHash($new_password);
784
        $this->setPreference('loginexpiration','0');
785
	    $this->setPreference('lockout','');
786
		$this->setPreference('loginfailed','0');
787
		$this->savePreferencesToDB();
788
        //set new password
789
        $now = TimeDate::getInstance()->nowDb();
790
		$query = "UPDATE $this->table_name SET user_hash='$user_hash', system_generated_password='$system_generated', pwd_last_changed='$now' where id='$this->id'";
791
		$this->db->query($query, true, "Error setting new password for $this->user_name: ");
792
        $_SESSION['hasExpiredPassword'] = '0';
793
	}
794
795
	/**
796
	 * Verify that the current password is correct and write the new password to the DB.
797
	 *
798
	 * @param string $user_password - Must be non null and at least 1 character.
799
	 * @param string $new_password - Must be non null and at least 1 character.
800
     * @param string $system_generated
801
	 * @return boolean - If passwords pass verification and query succeeds, return true, else return false.
802
	 */
803
	function change_password($user_password, $new_password, $system_generated = '0')
804
	{
805
	    global $mod_strings;
806
		global $current_user;
807
		$GLOBALS['log']->debug("Starting password change for $this->user_name");
808
809
		if (!isset ($new_password) || $new_password == "") {
810
			$this->error_string = $mod_strings['ERR_PASSWORD_CHANGE_FAILED_1'].$current_user->user_name.$mod_strings['ERR_PASSWORD_CHANGE_FAILED_2'];
811
			return false;
812
		}
813
814
815
		//check old password current user is not an admin or current user is an admin editing themselves
816
		if (!$current_user->isAdminForModule('Users')  || ($current_user->isAdminForModule('Users') && ($current_user->id == $this->id))) {
817
			//check old password first
818
			$row = self::findUserPassword($this->user_name, md5($user_password));
819
            if (empty($row)) {
820
				$GLOBALS['log']->warn("Incorrect old password for ".$this->user_name."");
821
				$this->error_string = $mod_strings['ERR_PASSWORD_INCORRECT_OLD_1'].$this->user_name.$mod_strings['ERR_PASSWORD_INCORRECT_OLD_2'];
822
				return false;
823
			}
824
		}
825
826
		$this->setNewPassword($new_password, $system_generated);
827
		return true;
828
	}
829
830
831
	function is_authenticated() {
832
		return $this->authenticated;
833
	}
834
835
	function fill_in_additional_list_fields() {
836
		$this->fill_in_additional_detail_fields();
837
	}
838
839
	function fill_in_additional_detail_fields() {
840
        // jmorais@dri Bug #56269
841
        parent::fill_in_additional_detail_fields();
842
        // ~jmorais@dri
843
		global $locale;
844
845
		$query = "SELECT u1.first_name, u1.last_name from users  u1, users  u2 where u1.id = u2.reports_to_id AND u2.id = '$this->id' and u1.deleted=0";
846
		$result = $this->db->query($query, true, "Error filling in additional detail fields");
847
848
		$row = $this->db->fetchByAssoc($result);
849
850
		if ($row != null) {
851
			$this->reports_to_name = stripslashes($row['first_name'].' '.$row['last_name']);
852
		} else {
853
			$this->reports_to_name = '';
854
		}
855
856
857
		$this->_create_proper_name_field();
858
	}
859
860
	public function retrieve_user_id(
861
	    $user_name
862
	    )
863
	{
864
	    $userFocus = new User;
865
	    $userFocus->retrieve_by_string_fields(array('user_name'=>$user_name));
866
	    if ( empty($userFocus->id) )
867
	        return false;
868
869
        return $userFocus->id;
870
	}
871
872
	/**
873
	 * @return -- returns a list of all users in the system.
0 ignored issues
show
Documentation introduced by
The doc-type -- could not be parsed: Unknown type name "--" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
874
	 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
875
	 * All Rights Reserved..
876
	 * Contributor(s): ______________________________________..
877
	 */
878
	function verify_data($ieVerified=true) {
879
		global $mod_strings, $current_user;
880
		$verified = TRUE;
881
882
		if (!empty ($this->id)) {
883
			// Make sure the user doesn't report to themselves.
884
			$reports_to_self = 0;
885
			$check_user = $this->reports_to_id;
886
			$already_seen_list = array ();
887
			while (!empty ($check_user)) {
888
				if (isset ($already_seen_list[$check_user])) {
889
					// This user doesn't actually report to themselves
890
					// But someone above them does.
891
					$reports_to_self = 1;
892
					break;
893
				}
894
				if ($check_user == $this->id) {
895
					$reports_to_self = 1;
896
					break;
897
				}
898
				$already_seen_list[$check_user] = 1;
899
				$query = "SELECT reports_to_id FROM users WHERE id='".$this->db->quote($check_user)."'";
900
				$result = $this->db->query($query, true, "Error checking for reporting-loop");
901
				$row = $this->db->fetchByAssoc($result);
902
				echo ("fetched: ".$row['reports_to_id']." from ".$check_user."<br>");
903
				$check_user = $row['reports_to_id'];
904
			}
905
906
			if ($reports_to_self == 1) {
907
				$this->error_string .= $mod_strings['ERR_REPORT_LOOP'];
908
				$verified = FALSE;
909
			}
910
		}
911
912
		$query = "SELECT user_name from users where user_name='$this->user_name' AND deleted=0";
913
		if(!empty($this->id))$query .=  " AND id<>'$this->id'";
914
		$result = $this->db->query($query, true, "Error selecting possible duplicate users: ");
915
		$dup_users = $this->db->fetchByAssoc($result);
916
917
		if (!empty($dup_users)) {
918
			$this->error_string .= $mod_strings['ERR_USER_NAME_EXISTS_1'].$this->user_name.$mod_strings['ERR_USER_NAME_EXISTS_2'];
919
			$verified = FALSE;
920
		}
921
922
		if (is_admin($current_user)) {
923
		    $remaining_admins = $this->db->getOne("SELECT COUNT(*) as c from users where is_admin = 1 AND deleted=0");
924
925
			if (($remaining_admins <= 1) && ($this->is_admin != '1') && ($this->id == $current_user->id)) {
926
				$GLOBALS['log']->debug("Number of remaining administrator accounts: {$remaining_admins}");
927
				$this->error_string .= $mod_strings['ERR_LAST_ADMIN_1'].$this->user_name.$mod_strings['ERR_LAST_ADMIN_2'];
928
				$verified = FALSE;
929
			}
930
		}
931
		///////////////////////////////////////////////////////////////////////
932
		////	InboundEmail verification failure
933
		if(!$ieVerified) {
934
			$verified = false;
935
			$this->error_string .= '<br />'.$mod_strings['ERR_EMAIL_NO_OPTS'];
936
		}
937
938
		return $verified;
939
	}
940
941
	function get_list_view_data() {
942
943
		global $mod_strings;
944
945
		$user_fields = parent::get_list_view_data();
946
947
		if ($this->is_admin)
948
			$user_fields['IS_ADMIN_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',$mod_strings['LBL_CHECKMARK']);
949
		elseif (!$this->is_admin) $user_fields['IS_ADMIN'] = '';
950
		if ($this->is_group)
951
			$user_fields['IS_GROUP_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',$mod_strings['LBL_CHECKMARK']);
952
		else
953
			$user_fields['IS_GROUP_IMAGE'] = '';
954
955
956
        if ($this->is_admin) {
957
      			$user_fields['IS_ADMIN_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',translate('LBL_CHECKMARK', 'Users'));
958
        } elseif (!$this->is_admin) {
959
              $user_fields['IS_ADMIN'] = '';
960
        }
961
962
      	if ($this->is_group) {
963
      		$user_fields['IS_GROUP_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',translate('LBL_CHECKMARK', 'Users'));
964
        } else {
965
            $user_fields['NAME'] = empty ($this->name) ? '' : $this->name;
966
        }
967
968
		$user_fields['REPORTS_TO_NAME'] = $this->reports_to_name;
969
970
971
		return $user_fields;
972
	}
973
974
	function list_view_parse_additional_sections(&$list_form) {
975
		return $list_form;
976
	}
977
978
979
980
981
    /**
982
     * getAllUsers
983
     *
984
     * Returns all active and inactive users
985
     * @return Array of all users in the system
986
     */
987
988
    public static function getAllUsers()
989
    {
990
        $active_users = get_user_array(FALSE);
991
        $inactive_users = get_user_array(FALSE, "Inactive");
992
        $result = $active_users + $inactive_users;
993
        asort($result);
994
        return $result;
995
    }
996
997
    /**
998
     * getActiveUsers
999
     *
1000
     * Returns all active users
1001
     * @return Array of active users in the system
1002
     */
1003
1004
    public static function getActiveUsers()
1005
    {
1006
        $active_users = get_user_array(FALSE);
1007
        asort($active_users);
1008
        return $active_users;
1009
    }
1010
1011
1012
1013
	function create_export_query($order_by, $where, $relate_link_join = '') {
1014
		include('modules/Users/field_arrays.php');
1015
1016
		$cols = '';
1017
		foreach($fields_array['User']['export_fields'] as $field) {
1018
			$cols .= (empty($cols)) ? '' : ', ';
1019
			$cols .= $field;
1020
		}
1021
1022
		$query = "SELECT {$cols} FROM users ";
1023
1024
		$where_auto = " users.deleted = 0";
1025
1026
		if ($where != "")
1027
			$query .= " WHERE $where AND ".$where_auto;
1028
		else
1029
			$query .= " WHERE ".$where_auto;
1030
1031
		// admin for module user is not be able to export a super-admin
1032
		global $current_user;
1033
		if(!$current_user->is_admin){
1034
			$query .= " AND users.is_admin=0";
1035
		}
1036
1037
		if ($order_by != "")
1038
			$query .= " ORDER BY $order_by";
1039
		else
1040
			$query .= " ORDER BY users.user_name";
1041
1042
		return $query;
1043
	}
1044
1045
	/** Returns a list of the associated users
1046
	 * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
1047
	 * All Rights Reserved..
1048
	 * Contributor(s): ______________________________________..
1049
	*/
1050
	function get_meetings() {
1051
		// First, get the list of IDs.
1052
		$query = "SELECT meeting_id as id from meetings_users where user_id='$this->id' AND deleted=0";
1053
		return $this->build_related_list($query, new Meeting());
1054
	}
1055
	function get_calls() {
1056
		// First, get the list of IDs.
1057
		$query = "SELECT call_id as id from calls_users where user_id='$this->id' AND deleted=0";
1058
		return $this->build_related_list($query, new Call());
1059
	}
1060
1061
	/**
1062
	 * generates Javascript to display I-E mail counts, both personal and group
1063
	 */
1064
	function displayEmailCounts() {
1065
		global $theme;
1066
		$new = translate('LBL_NEW', 'Emails');
1067
		$default = 'index.php?module=Emails&action=ListView&assigned_user_id='.$this->id;
1068
		$count = '';
1069
		$verts = array('Love', 'Links', 'Pipeline', 'RipCurl', 'SugarLite');
1070
1071
		if($this->hasPersonalEmail()) {
1072
			$r = $this->db->query('SELECT count(*) AS c FROM emails WHERE deleted=0 AND assigned_user_id = \''.$this->id.'\' AND type = \'inbound\' AND status = \'unread\'');
1073
			$a = $this->db->fetchByAssoc($r);
1074
			if(in_array($theme, $verts)) {
1075
				$count .= '<br />';
1076
			} else {
1077
				$count .= '&nbsp;&nbsp;&nbsp;&nbsp;';
1078
			}
1079
			$count .= '<a href='.$default.'&type=inbound>'.translate('LBL_LIST_TITLE_MY_INBOX', 'Emails').': ('.$a['c'].' '.$new.')</a>';
1080
1081
			if(!in_array($theme, $verts)) {
1082
				$count .= ' - ';
1083
			}
1084
		}
1085
1086
		$r = $this->db->query('SELECT id FROM users WHERE users.is_group = 1 AND deleted = 0');
1087
		$groupIds = '';
1088
		$groupNew = '';
1089
		while($a = $this->db->fetchByAssoc($r)) {
1090
			if($groupIds != '') {$groupIds .= ', ';}
1091
			$groupIds .= "'".$a['id']."'";
1092
		}
1093
1094
		$total = 0;
1095
		if(strlen($groupIds) > 0) {
1096
			$groupQuery = 'SELECT count(*) AS c FROM emails ';
1097
			$groupQuery .= ' WHERE emails.deleted=0 AND emails.assigned_user_id IN ('.$groupIds.') AND emails.type = \'inbound\' AND emails.status = \'unread\'';
1098
			$r = $this->db->query($groupQuery);
1099
			if(is_resource($r)) {
1100
				$a = $this->db->fetchByAssoc($r);
1101
				if($a['c'] > 0) {
1102
					$total = $a['c'];
1103
				}
1104
			}
1105
		}
1106
		if(in_array($theme, $verts)) $count .= '<br />';
1107
		if(empty($count)) $count .= '&nbsp;&nbsp;&nbsp;&nbsp;';
1108
		$count .= '<a href=index.php?module=Emails&action=ListViewGroup>'.translate('LBL_LIST_TITLE_GROUP_INBOX', 'Emails').': ('.$total.' '.$new.')</a>';
1109
1110
		$out  = '<script type="text/javascript" language="Javascript">';
1111
		$out .= 'var welcome = document.getElementById("welcome");';
1112
		$out .= 'var welcomeContent = welcome.innerHTML;';
1113
		$out .= 'welcome.innerHTML = welcomeContent + "'.$count.'";';
1114
		$out .= '</script>';
1115
1116
		echo $out;
1117
	}
1118
1119
	function getPreferredEmail() {
1120
		$ret = array ();
1121
		$nameEmail = $this->getUsersNameAndEmail();
1122
		$prefAddr = $nameEmail['email'];
1123
		$fullName = $nameEmail['name'];
1124
		if (empty ($prefAddr)) {
1125
			$nameEmail = $this->getSystemDefaultNameAndEmail();
1126
			$prefAddr = $nameEmail['email'];
1127
			$fullName = $nameEmail['name'];
1128
		} // if
1129
		$fullName = from_html($fullName);
1130
		$ret['name'] = $fullName;
1131
		$ret['email'] = $prefAddr;
1132
		return $ret;
1133
	}
1134
1135
	function getUsersNameAndEmail()
1136
	{
1137
	    // Bug #48555 Not User Name Format of User's locale.
1138
	    $this->_create_proper_name_field();
1139
1140
		$prefAddr = $this->emailAddress->getPrimaryAddress($this);
1141
1142
		if (empty ($prefAddr)) {
1143
			$prefAddr = $this->emailAddress->getReplyToAddress($this);
1144
		}
1145
		return array('email' => $prefAddr , 'name' => $this->name);
1146
1147
	} // fn
1148
1149
	function getSystemDefaultNameAndEmail() {
1150
1151
		$email = new Email();
1152
		$return = $email->getSystemDefaultEmail();
1153
		$prefAddr = $return['email'];
1154
		$fullName = $return['name'];
1155
		return array('email' => $prefAddr , 'name' => $fullName);
1156
	} // fn
1157
1158
	/**
1159
	 * sets User email default in config.php if not already set by install - i.
1160
	 * e., upgrades
1161
	 */
1162
	function setDefaultsInConfig() {
1163
		global $sugar_config;
1164
		$sugar_config['email_default_client'] = 'sugar';
1165
		$sugar_config['email_default_editor'] = 'html';
1166
		ksort($sugar_config);
1167
		write_array_to_file('sugar_config', $sugar_config, 'config.php');
1168
		return $sugar_config;
1169
	}
1170
1171
    /**
1172
     * returns User's email address based on descending order of preferences
1173
     *
1174
     * @param string id GUID of target user if needed
1175
     * @return array Assoc array for an email and name
1176
     */
1177
    function getEmailInfo($id='') {
1178
        $user = $this;
1179
        if(!empty($id)) {
1180
            $user = new User();
1181
            $user->retrieve($id);
1182
        }
1183
1184
        // from name
1185
        $fromName = $user->getPreference('mail_fromname');
1186
        if(empty($fromName)) {
1187
        	// cn: bug 8586 - localized name format
1188
            $fromName = $user->full_name;
1189
        }
1190
1191
        // from address
1192
        $fromaddr = $user->getPreference('mail_fromaddress');
1193
        if(empty($fromaddr)) {
1194
            if(!empty($user->email1) && isset($user->email1)) {
1195
                $fromaddr = $user->email1;
1196
            } elseif(!empty($user->email2) && isset($user->email2)) {
1197
                $fromaddr = $user->email2;
1198
            } else {
1199
                $r = $user->db->query("SELECT value FROM config WHERE name = 'fromaddress'");
1200
                $a = $user->db->fetchByAssoc($r);
1201
                $fromddr = $a['value'];
1202
            }
1203
        }
1204
1205
        $ret['name'] = $fromName;
1206
        $ret['email'] = $fromaddr;
1207
1208
        return $ret;
1209
    }
1210
1211
	/**
1212
	 * returns opening <a href=xxxx for a contact, account, etc
1213
	 * cascades from User set preference to System-wide default
1214
	 * @return string	link
1215
	 * @param attribute the email addy
1216
	 * @param focus the parent bean
1217
	 * @param contact_id
1218
	 * @param return_module
1219
	 * @param return_action
1220
	 * @param return_id
1221
	 * @param class
1222
	 */
1223
	function getEmailLink2($emailAddress, &$focus, $contact_id='', $ret_module='', $ret_action='DetailView', $ret_id='', $class='') {
1224
		$emailLink = '';
1225
		global $sugar_config;
1226
1227
		if(!isset($sugar_config['email_default_client'])) {
1228
			$this->setDefaultsInConfig();
1229
		}
1230
1231
		$userPref = $this->getPreference('email_link_type');
1232
		$defaultPref = $sugar_config['email_default_client'];
1233
		if($userPref != '') {
1234
			$client = $userPref;
1235
		} else {
1236
			$client = $defaultPref;
1237
		}
1238
1239
		if($client == 'sugar') {
1240
			$email = '';
1241
			$to_addrs_ids = '';
1242
			$to_addrs_names = '';
1243
			$to_addrs_emails = '';
1244
1245
			$fullName = !empty($focus->name) ? $focus->name : '';
1246
1247
			if(empty($ret_module)) $ret_module = $focus->module_dir;
1248
			if(empty($ret_id)) $ret_id = $focus->id;
1249
			if($focus->object_name == 'Contact') {
1250
				$contact_id = $focus->id;
1251
				$to_addrs_ids = $focus->id;
1252
				// Bug #48555 Not User Name Format of User's locale.
1253
				$focus->_create_proper_name_field();
1254
			    $fullName = $focus->name;
1255
			    $to_addrs_names = $fullName;
1256
				$to_addrs_emails = $focus->email1;
1257
			}
1258
1259
			$emailLinkUrl = 'contact_id='.$contact_id.
1260
				'&parent_type='.$focus->module_dir.
1261
				'&parent_id='.$focus->id.
1262
				'&parent_name='.urlencode($fullName).
1263
				'&to_addrs_ids='.$to_addrs_ids.
1264
				'&to_addrs_names='.urlencode($to_addrs_names).
1265
				'&to_addrs_emails='.urlencode($to_addrs_emails).
1266
				'&to_email_addrs='.urlencode($fullName . '&nbsp;&lt;' . $emailAddress . '&gt;').
1267
				'&return_module='.$ret_module.
1268
				'&return_action='.$ret_action.
1269
				'&return_id='.$ret_id;
1270
1271
    		//Generate the compose package for the quick create options.
1272
    		//$json = getJSONobj();
1273
    		//$composeOptionsLink = $json->encode( array('composeOptionsLink' => $emailLinkUrl,'id' => $focus->id) );
1274
			require_once('modules/Emails/EmailUI.php');
1275
            $eUi = new EmailUI();
1276
            $j_quickComposeOptions = $eUi->generateComposePackageForQuickCreateFromComposeUrl($emailLinkUrl, true);
1277
1278
    		$emailLink = "<a href='javascript:void(0);' onclick='SUGAR.quickCompose.init($j_quickComposeOptions);' class='$class'>";
1279
1280
		} else {
1281
			// straight mailto:
1282
			$emailLink = '<a href="mailto:'.$emailAddress.'" class="'.$class.'">';
1283
		}
1284
1285
		return $emailLink;
1286
	}
1287
1288
	/**
1289
	 * returns opening <a href=xxxx for a contact, account, etc
1290
	 * cascades from User set preference to System-wide default
1291
	 * @return string	link
1292
	 * @param attribute the email addy
1293
	 * @param focus the parent bean
1294
	 * @param contact_id
1295
	 * @param return_module
1296
	 * @param return_action
1297
	 * @param return_id
1298
	 * @param class
1299
	 */
1300
	function getEmailLink($attribute, &$focus, $contact_id='', $ret_module='', $ret_action='DetailView', $ret_id='', $class='') {
1301
	    $emailLink = '';
1302
		global $sugar_config;
1303
1304
		if(!isset($sugar_config['email_default_client'])) {
1305
			$this->setDefaultsInConfig();
1306
		}
1307
1308
		$userPref = $this->getPreference('email_link_type');
1309
		$defaultPref = $sugar_config['email_default_client'];
1310
		if($userPref != '') {
1311
			$client = $userPref;
1312
		} else {
1313
			$client = $defaultPref;
1314
		}
1315
1316
		if($client == 'sugar') {
1317
			$email = '';
1318
			$to_addrs_ids = '';
1319
			$to_addrs_names = '';
1320
			$to_addrs_emails = '';
1321
1322
            $fullName = !empty($focus->name) ? $focus->name : '';
1323
1324
			if(!empty($focus->$attribute)) {
1325
				$email = $focus->$attribute;
1326
			}
1327
1328
1329
			if(empty($ret_module)) $ret_module = $focus->module_dir;
1330
			if(empty($ret_id)) $ret_id = $focus->id;
1331
			if($focus->object_name == 'Contact') {
1332
				// Bug #48555 Not User Name Format of User's locale.
1333
				$focus->_create_proper_name_field();
1334
			    $fullName = $focus->name;
1335
			    $contact_id = $focus->id;
1336
				$to_addrs_ids = $focus->id;
1337
				$to_addrs_names = $fullName;
1338
				$to_addrs_emails = $focus->email1;
1339
			}
1340
1341
			$emailLinkUrl = 'contact_id='.$contact_id.
1342
				'&parent_type='.$focus->module_dir.
1343
				'&parent_id='.$focus->id.
1344
				'&parent_name='.urlencode($fullName).
1345
				'&to_addrs_ids='.$to_addrs_ids.
1346
				'&to_addrs_names='.urlencode($to_addrs_names).
1347
				'&to_addrs_emails='.urlencode($to_addrs_emails).
1348
				'&to_email_addrs='.urlencode($fullName . '&nbsp;&lt;' . $email . '&gt;').
1349
				'&return_module='.$ret_module.
1350
				'&return_action='.$ret_action.
1351
				'&return_id='.$ret_id;
1352
1353
			//Generate the compose package for the quick create options.
1354
    		require_once('modules/Emails/EmailUI.php');
1355
            $eUi = new EmailUI();
1356
            $j_quickComposeOptions = $eUi->generateComposePackageForQuickCreateFromComposeUrl($emailLinkUrl, true);
1357
    		$emailLink = "<a href='javascript:void(0);' onclick='SUGAR.quickCompose.init($j_quickComposeOptions);' class='$class'>";
1358
1359
		} else {
1360
			// straight mailto:
1361
			$emailLink = '<a href="mailto:'.$focus->$attribute.'" class="'.$class.'">';
1362
		}
1363
1364
		return $emailLink;
1365
	}
1366
1367
1368
	/**
1369
	 * gets a human-readable explanation of the format macro
1370
	 * @return string Human readable name format
1371
	 */
1372
	function getLocaleFormatDesc() {
1373
		global $locale;
1374
		global $mod_strings;
1375
		global $app_strings;
1376
1377
		$format['f'] = $mod_strings['LBL_LOCALE_DESC_FIRST'];
1378
		$format['l'] = $mod_strings['LBL_LOCALE_DESC_LAST'];
1379
		$format['s'] = $mod_strings['LBL_LOCALE_DESC_SALUTATION'];
1380
		$format['t'] = $mod_strings['LBL_LOCALE_DESC_TITLE'];
1381
1382
		$name['f'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST'];
1383
		$name['l'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST'];
1384
		$name['s'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION'];
1385
		$name['t'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_TITLE'];
1386
1387
		$macro = $locale->getLocaleFormatMacro();
1388
1389
		$ret1 = '';
1390
		$ret2 = '';
1391
		for($i=0; $i<strlen($macro); $i++) {
1392
			if(array_key_exists($macro{$i}, $format)) {
1393
				$ret1 .= "<i>".$format[$macro{$i}]."</i>";
1394
				$ret2 .= "<i>".$name[$macro{$i}]."</i>";
1395
			} else {
1396
				$ret1 .= $macro{$i};
1397
				$ret2 .= $macro{$i};
1398
			}
1399
		}
1400
		return $ret1."<br />".$ret2;
1401
	}
1402
1403
1404
    /*
1405
     *
1406
     * Here are the multi level admin access check functions.
1407
     *
1408
     */
1409
    /**
1410
     * Helper function to remap some modules around ACL wise
1411
     *
1412
     * @return string
1413
     */
1414
    protected function _fixupModuleForACL($module) {
1415
        if($module=='ContractTypes') {
1416
            $module = 'Contracts';
1417
        }
1418
        if(preg_match('/Product[a-zA-Z]*/',$module)) {
1419
            $module = 'Products';
1420
        }
1421
1422
        return $module;
1423
    }
1424
    /**
1425
     * Helper function that enumerates the list of modules and checks if they are an admin/dev.
1426
     * The code was just too similar to copy and paste.
1427
     *
1428
     * @return array
1429
     */
1430
    protected function _getModulesForACL($type='dev'){
1431
        $isDev = $type=='dev';
1432
        $isAdmin = $type=='admin';
1433
1434
        global $beanList;
1435
        $myModules = array();
1436
1437
        if (!is_array($beanList) ) {
1438
            return $myModules;
1439
        }
1440
1441
        // These modules don't take kindly to the studio trying to play about with them.
1442
        static $ignoredModuleList = array('iFrames','Feeds','Home','Dashboard','Calendar','Activities','Reports');
1443
1444
1445
        $actions = ACLAction::getUserActions($this->id);
1446
1447
        foreach ($beanList as $module=>$val) {
1448
            // Remap the module name
1449
            $module = $this->_fixupModuleForACL($module);
1450
            if (in_array($module,$myModules)) {
1451
                // Already have the module in the list
1452
                continue;
1453
            }
1454
            if (in_array($module,$ignoredModuleList)) {
1455
                // You can't develop on these modules.
1456
                continue;
1457
            }
1458
1459
            $focus = SugarModule::get($module)->loadBean();
1460
            if ( $focus instanceOf SugarBean ) {
1461
                $key = $focus->acltype;
1462
            } else {
1463
                $key = 'module';
1464
            }
1465
1466
            if (($this->isAdmin() && isset($actions[$module][$key]))
1467
                ) {
1468
                $myModules[] = $module;
1469
            }
1470
        }
1471
1472
        return $myModules;
1473
    }
1474
    /**
1475
     * Is this user a system wide admin
1476
     *
1477
     * @return bool
1478
     */
1479
    public function isAdmin() {
1480
        if(isset($this->is_admin)
1481
           &&($this->is_admin == '1' || $this->is_admin === 'on')){
1482
            return true;
1483
        }
1484
        return false;
1485
    }
1486
    /**
1487
     * Is this user a developer for any module
1488
     *
1489
     * @return bool
1490
     */
1491
    public function isDeveloperForAnyModule() {
1492
        if(empty($this->id)) {
1493
            // empty user is no developer
1494
            return false;
1495
        }
1496
        if ($this->isAdmin()) {
1497
            return true;
1498
        }
1499
        return false;
1500
    }
1501
    /**
1502
     * List the modules a user has developer access to
1503
     *
1504
     * @return array
1505
     */
1506
    public function getDeveloperModules() {
1507
        static $developerModules;
1508
        if (!isset($_SESSION[$this->user_name.'_get_developer_modules_for_user']) ) {
1509
            $_SESSION[$this->user_name.'_get_developer_modules_for_user'] = $this->_getModulesForACL('dev');
1510
        }
1511
1512
        return $_SESSION[$this->user_name.'_get_developer_modules_for_user'];
1513
    }
1514
    /**
1515
     * Is this user a developer for the specified module
1516
     *
1517
     * @return bool
1518
     */
1519
    public function isDeveloperForModule($module) {
1520
        if(empty($this->id)) {
1521
            // empty user is no developer
1522
            return false;
1523
        }
1524
        if ($this->isAdmin()) {
1525
            return true;
1526
        }
1527
1528
        $devModules = $this->getDeveloperModules();
1529
1530
        $module = $this->_fixupModuleForACL($module);
1531
1532
        if (in_array($module,$devModules) ) {
1533
            return true;
1534
        }
1535
1536
        return false;
1537
    }
1538
    /**
1539
     * List the modules a user has admin access to
1540
     *
1541
     * @return array
1542
     */
1543
    public function getAdminModules() {
1544
        if (!isset($_SESSION[$this->user_name.'_get_admin_modules_for_user']) ) {
1545
            $_SESSION[$this->user_name.'_get_admin_modules_for_user'] = $this->_getModulesForACL('admin');
1546
        }
1547
1548
        return $_SESSION[$this->user_name.'_get_admin_modules_for_user'];
1549
    }
1550
    /**
1551
     * Is this user an admin for the specified module
1552
     *
1553
     * @return bool
1554
     */
1555
    public function isAdminForModule($module) {
1556
        if(empty($this->id)) {
1557
            // empty user is no admin
1558
            return false;
1559
        }
1560
        if ($this->isAdmin()) {
1561
            return true;
1562
        }
1563
1564
        $adminModules = $this->getAdminModules();
1565
1566
        $module = $this->_fixupModuleForACL($module);
1567
1568
        if (in_array($module,$adminModules) ) {
1569
            return true;
1570
        }
1571
1572
        return false;
1573
    }
1574
	/**
1575
	 * Whether or not based on the user's locale if we should show the last name first.
1576
	 *
1577
	 * @return bool
1578
	 */
1579
	public function showLastNameFirst(){
1580
		global $locale;
1581
    	$localeFormat = $locale->getLocaleFormatMacro($this);
1582
		if ( strpos($localeFormat,'l') > strpos($localeFormat,'f') ) {
1583
                    return false;
1584
        }else {
1585
        	return true;
1586
        }
1587
	}
1588
1589
   function create_new_list_query($order_by, $where,$filter=array(),$params=array(), $show_deleted = 0,$join_type='', $return_array = false,$parentbean=null, $singleSelect = false,$ifListForExport = false)
1590
   {	//call parent method, specifying for array to be returned
1591
   	$ret_array = parent::create_new_list_query($order_by, $where,$filter,$params, $show_deleted,$join_type, true,$parentbean, $singleSelect,$ifListForExport);
1592
1593
   	//if this is being called from webservices, then run additional code
1594
   	if(!empty($GLOBALS['soap_server_object'])){
1595
1596
		//if this is a single select, then secondary queries are being run that may result in duplicate rows being returned through the
1597
		//left joins with meetings/tasks/call.  We need to change the left joins to include a null check (bug 40250)
1598
	   	if($singleSelect)
1599
	    	{
1600
			//retrieve the 'from' string and make lowercase for easier manipulation
1601
		        $left_str = strtolower($ret_array['from']);
1602
		        $lefts = explode('left join', $left_str);
1603
		        $new_left_str = '';
1604
1605
        		//explode on the left joins and process each one
1606
		        foreach($lefts as $ljVal){
1607
		        	//grab the join alias
1608
	        	        $onPos = strpos( $ljVal, ' on');
1609
	                	if($onPos === false){
1610
		                	$new_left_str .=' '.$ljVal.' ';
1611
		                        continue;
1612
		                }
1613
		                $spacePos = strrpos(substr($ljVal, 0, $onPos),' ');
1614
		                $alias = substr($ljVal,$spacePos,$onPos-$spacePos);
1615
1616
		                //add null check to end of the Join statement
1617
                        // Bug #46390 to use id_c field instead of id field for custom tables
1618
                        if(substr($alias, -5) != '_cstm')
1619
                        {
1620
                            $ljVal ='  LEFT JOIN '.$ljVal.' and '.$alias.'.id is null ';
1621
                        }
1622
                        else
1623
                        {
1624
                            $ljVal ='  LEFT JOIN '.$ljVal.' and '.$alias.'.id_c is null ';
1625
                        }
1626
1627
		                //add statement into new string
1628
		                $new_left_str .= $ljVal;
1629
		         }
1630
	        	 //replace the old string with the new one
1631
        		 $ret_array['from'] = $new_left_str;
1632
	    	}
1633
   	}
1634
1635
   		//return array or query string
1636
   		if($return_array)
1637
    	{
1638
    		return $ret_array;
1639
    	}
1640
1641
    	return  $ret_array['select'] . $ret_array['from'] . $ret_array['where']. $ret_array['order_by'];
1642
1643
1644
1645
   }
1646
1647
    /**
1648
     * Get user first day of week.
1649
     *
1650
     * @param [User] $user user object, current user if not specified
0 ignored issues
show
Documentation introduced by
The doc-type [User] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
Bug introduced by
There is no parameter named $user. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1651
     * @return int : 0 = Sunday, 1 = Monday, etc...
1652
     */
1653
    public function get_first_day_of_week()
1654
    {
1655
        $fdow = $this->getPreference('fdow');
1656
        if (empty($fdow))
1657
        {
1658
            $fdow = 0;
1659
        }
1660
1661
        return $fdow;
1662
    }
1663
1664
    /**
1665
     * Method for password generation
1666
     *
1667
     * @static
1668
     * @return string password
1669
     */
1670
    public static function generatePassword()
1671
    {
1672
        $res = $GLOBALS['sugar_config']['passwordsetting'];
1673
        $charBKT = '';
1674
        //chars to select from
1675
        $LOWERCASE = "abcdefghijklmnpqrstuvwxyz";
1676
        $NUMBER = "0123456789";
1677
        $UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1678
        $SPECIAL = '~!@#$%^&*()_+=-{}|';
1679
        $condition = 0;
1680
        $charBKT .= $UPPERCASE . $LOWERCASE . $NUMBER;
1681
        $password = "";
1682
            $length = '6';
1683
1684
        // Create random characters for the ones that doesnt have requirements
1685
        for ($i=0; $i < $length - $condition; $i ++)  // loop and create password
1686
        {
1687
            $password = $password . substr ($charBKT, rand() % strlen($charBKT), 1);
1688
        }
1689
1690
        return $password;
1691
    }
1692
1693
    /**
1694
     * Send new password or link to user
1695
     *
1696
     * @param string $templateId Id of email template
1697
     * @param array $additionalData additional params: link, url, password
1698
     * @return array status: true|false, message: error message, if status = false and message = '' it means that send method has returned false
1699
     */
1700
    public function sendEmailForPassword($templateId, array $additionalData = array())
1701
    {
1702
        global $sugar_config, $current_user;
1703
        $mod_strings = return_module_language('', 'Users');
1704
        $result = array(
1705
            'status' => false,
1706
            'message' => ''
1707
        );
1708
1709
        $emailTemp = new EmailTemplate();
1710
        $emailTemp->disable_row_level_security = true;
1711
        if ($emailTemp->retrieve($templateId) == '')
1712
        {
1713
            $result['message'] = $mod_strings['LBL_EMAIL_TEMPLATE_MISSING'];
1714
            return $result;
1715
        }
1716
1717
        //replace instance variables in email templates
1718
        $htmlBody = $emailTemp->body_html;
1719
        $body = $emailTemp->body;
1720
        if (isset($additionalData['link']) && $additionalData['link'] == true)
1721
        {
1722
            $htmlBody = str_replace('$contact_user_link_guid', $additionalData['url'], $htmlBody);
1723
            $body = str_replace('$contact_user_link_guid', $additionalData['url'], $body);
1724
        }
1725
        else
1726
        {
1727
            $htmlBody = str_replace('$contact_user_user_hash', $additionalData['password'], $htmlBody);
1728
            $body = str_replace('$contact_user_user_hash', $additionalData['password'], $body);
1729
        }
1730
        // Bug 36833 - Add replacing of special value $instance_url
1731
        $htmlBody = str_replace('$config_site_url', $sugar_config['site_url'], $htmlBody);
1732
        $body = str_replace('$config_site_url', $sugar_config['site_url'], $body);
1733
1734
        $htmlBody = str_replace('$contact_user_user_name', $this->user_name, $htmlBody);
1735
        $htmlBody = str_replace('$contact_user_pwd_last_changed', TimeDate::getInstance()->nowDb(), $htmlBody);
1736
        $body = str_replace('$contact_user_user_name', $this->user_name, $body);
1737
        $body = str_replace('$contact_user_pwd_last_changed', TimeDate::getInstance()->nowDb(), $body);
1738
        $emailTemp->body_html = $htmlBody;
1739
        $emailTemp->body = $body;
1740
1741
        $itemail = $this->emailAddress->getPrimaryAddress($this);
1742
        //retrieve IT Admin Email
1743
        //_ppd( $emailTemp->body_html);
1744
        //retrieve email defaults
1745
        $emailObj = new Email();
1746
        $defaults = $emailObj->getSystemDefaultEmail();
1747
        require_once('include/SugarPHPMailer.php');
1748
        $mail = new SugarPHPMailer();
1749
        $mail->setMailerForSystem();
1750
        //$mail->IsHTML(true);
1751
        $mail->From = $defaults['email'];
1752
        $mail->FromName = $defaults['name'];
1753
        $mail->ClearAllRecipients();
1754
        $mail->ClearReplyTos();
1755
        $mail->Subject = from_html($emailTemp->subject);
1756
        if ($emailTemp->text_only != 1)
1757
        {
1758
            $mail->IsHTML(true);
1759
            $mail->Body = from_html($emailTemp->body_html);
1760
            $mail->AltBody = from_html($emailTemp->body);
1761
        }
1762
        else
1763
        {
1764
            $mail->Body_html = from_html($emailTemp->body_html);
1765
            $mail->Body = from_html($emailTemp->body);
1766
        }
1767
        if ($mail->Body == '' && $current_user->is_admin)
1768
        {
1769
            global $app_strings;
1770
            $result['message'] = $app_strings['LBL_EMAIL_TEMPLATE_EDIT_PLAIN_TEXT'];
1771
            return $result;
1772
        }
1773
        if ($mail->Mailer == 'smtp' && $mail->Host =='' && $current_user->is_admin)
1774
        {
1775
            $result['message'] = $mod_strings['ERR_SERVER_SMTP_EMPTY'];
1776
            return $result;
1777
        }
1778
1779
        $mail->prepForOutbound();
1780
        $hasRecipients = false;
1781
1782
        if (!empty($itemail))
1783
        {
1784
            if ($hasRecipients)
1785
            {
1786
                $mail->AddBCC($itemail);
1787
            }
1788
            else
1789
            {
1790
                $mail->AddAddress($itemail);
1791
            }
1792
            $hasRecipients = true;
1793
        }
1794
        if ($hasRecipients)
1795
        {
1796
            $result['status'] = @$mail->Send();
1797
        }
1798
1799
        if ($result['status'] == true)
1800
        {
1801
            $emailObj->team_id = 1;
1802
            $emailObj->to_addrs = '';
1803
            $emailObj->type = 'archived';
1804
            $emailObj->deleted = '0';
1805
            $emailObj->name = $mail->Subject ;
1806
            $emailObj->description = $mail->Body;
1807
            $emailObj->description_html = null;
1808
            $emailObj->from_addr = $mail->From;
1809
            $emailObj->parent_type = 'User';
1810
            $emailObj->date_sent = TimeDate::getInstance()->nowDb();
1811
            $emailObj->modified_user_id = '1';
1812
            $emailObj->created_by = '1';
1813
            $emailObj->status = 'sent';
1814
            $emailObj->save();
1815
            if (!isset($additionalData['link']) || $additionalData['link'] == false)
1816
            {
1817
                $this->setNewPassword($additionalData['password'], '1');
1818
            }
1819
        }
1820
1821
        return $result;
1822
    }
1823
1824
    // Bug #48014 Must to send password to imported user if this action is required
1825
    function afterImportSave()
1826
    {
1827
        if(
1828
            $this->user_hash == false
1829
            && !$this->is_group
1830
            && !$this->portal_only
1831
            && isset($GLOBALS['sugar_config']['passwordsetting']['SystemGeneratedPasswordON'])
1832
            && $GLOBALS['sugar_config']['passwordsetting']['SystemGeneratedPasswordON']
1833
        )
1834
        {
1835
            $backUpPost = $_POST;
1836
            $_POST = array(
1837
                'userId' => $this->id
1838
            );
1839
            ob_start();
1840
            require('modules/Users/GeneratePassword.php');
1841
            $result = ob_get_clean();
1842
            $_POST = $backUpPost;
1843
            return $result == true;
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $result of type string to the boolean true. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
1844
        }
1845
    }
1846
1847
    /**
1848
     * Checks if the passed email is primary.
1849
     * 
1850
     * @param string $email
1851
     * @return bool Returns TRUE if the passed email is primary.
1852
     */
1853
    public function isPrimaryEmail($email)
1854
    {
1855
        if (!empty($this->email1) && !empty($email) && strcasecmp($this->email1, $email) == 0) {
1856
            return true;
1857
        } else {
1858
            return false;
1859
        }
1860
    }
1861
}
1862