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
|
156 |
|
function __construct() { |
114
|
156 |
|
parent::__construct(); |
115
|
|
|
|
116
|
156 |
|
$this->_loadUserPreferencesFocus(); |
117
|
156 |
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead |
121
|
|
|
*/ |
122
|
|
|
function User(){ |
123
|
|
|
$deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; |
124
|
|
|
if(isset($GLOBALS['log'])) { |
125
|
|
|
$GLOBALS['log']->deprecated($deprecatedMessage); |
126
|
|
|
} |
127
|
|
|
else { |
128
|
|
|
trigger_error($deprecatedMessage, E_USER_DEPRECATED); |
129
|
|
|
} |
130
|
|
|
self::__construct(); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
|
134
|
156 |
|
protected function _loadUserPreferencesFocus() |
135
|
|
|
{ |
136
|
156 |
|
$this->_userPreferenceFocus = new UserPreference($this); |
137
|
156 |
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* returns an admin user |
141
|
|
|
*/ |
142
|
1 |
|
public function getSystemUser() |
143
|
|
|
{ |
144
|
1 |
|
if (null === $this->retrieve('1')) |
145
|
|
|
// handle cases where someone deleted user with id "1" |
146
|
|
|
$this->retrieve_by_string_fields(array( |
147
|
|
|
'status' => 'Active', |
148
|
|
|
'is_admin' => '1', |
149
|
|
|
)); |
150
|
|
|
|
151
|
1 |
|
return $this; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* convenience function to get user's default signature |
157
|
|
|
*/ |
158
|
1 |
|
function getDefaultSignature() { |
159
|
1 |
|
if($defaultId = $this->getPreference('signature_default')) { |
160
|
|
|
return $this->getSignature($defaultId); |
161
|
|
|
} else { |
162
|
1 |
|
return array(); |
163
|
|
|
} |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* retrieves the signatures for a user |
168
|
|
|
* @param string id ID of user_signature |
169
|
|
|
* @return array ID, signature, and signature_html |
170
|
|
|
*/ |
171
|
1 |
|
public function getSignature($id) |
172
|
|
|
{ |
173
|
1 |
|
$signatures = $this->getSignaturesArray(); |
174
|
|
|
|
175
|
1 |
|
return isset($signatures[$id]) ? $signatures[$id] : FALSE; |
176
|
|
|
} |
177
|
|
|
|
178
|
3 |
|
function getSignaturesArray() { |
179
|
3 |
|
$q = 'SELECT * FROM users_signatures WHERE user_id = \''.$this->id.'\' AND deleted = 0 ORDER BY name ASC'; |
180
|
3 |
|
$r = $this->db->query($q); |
181
|
|
|
|
182
|
|
|
// provide "none" |
183
|
3 |
|
$sig = array(""=>""); |
184
|
|
|
|
185
|
3 |
|
while($a = $this->db->fetchByAssoc($r)) { |
186
|
|
|
$sig[$a['id']] = $a; |
187
|
|
|
} |
188
|
|
|
|
189
|
3 |
|
return $sig; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* retrieves any signatures that the User may have created as <select> |
194
|
|
|
*/ |
195
|
1 |
|
public function getSignatures( |
196
|
|
|
$live = false, |
197
|
|
|
$defaultSig = '', |
198
|
|
|
$forSettings = false |
199
|
|
|
) |
200
|
|
|
{ |
201
|
1 |
|
$sig = $this->getSignaturesArray(); |
202
|
1 |
|
$sigs = array(); |
203
|
1 |
|
foreach ($sig as $key => $arr) |
204
|
|
|
{ |
205
|
1 |
|
$sigs[$key] = !empty($arr['name']) ? $arr['name'] : ''; |
206
|
|
|
} |
207
|
|
|
|
208
|
1 |
|
$change = ''; |
209
|
1 |
|
if(!$live) { |
210
|
1 |
|
$change = ($forSettings) ? "onChange='displaySignatureEdit();'" : "onChange='setSigEditButtonVisibility();'"; |
211
|
|
|
} |
212
|
|
|
|
213
|
1 |
|
$id = (!$forSettings) ? 'signature_id' : 'signature_idDisplay'; |
214
|
|
|
|
215
|
1 |
|
$out = "<select {$change} id='{$id}' name='{$id}'>"; |
216
|
1 |
|
$out .= get_select_options_with_id($sigs, $defaultSig).'</select>'; |
217
|
|
|
|
218
|
1 |
|
return $out; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* returns buttons and JS for signatures |
223
|
|
|
*/ |
224
|
1 |
|
function getSignatureButtons($jscall='', $defaultDisplay=false) { |
225
|
1 |
|
global $mod_strings; |
226
|
|
|
|
227
|
1 |
|
$jscall = empty($jscall) ? 'open_email_signature_form' : $jscall; |
228
|
|
|
|
229
|
1 |
|
$butts = "<input class='button' onclick='javascript:{$jscall}(\"\", \"{$this->id}\");' value='{$mod_strings['LBL_BUTTON_CREATE']}' type='button'> "; |
230
|
1 |
|
if($defaultDisplay) { |
231
|
1 |
|
$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"> |
232
|
1 |
|
</span>'; |
233
|
|
|
} else { |
234
|
1 |
|
$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"> |
235
|
1 |
|
</span>'; |
236
|
|
|
} |
237
|
1 |
|
return $butts; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* performs a rudimentary check to verify if a given user has setup personal |
242
|
|
|
* InboundEmail |
243
|
|
|
* |
244
|
|
|
* @return bool |
245
|
|
|
*/ |
246
|
3 |
|
public function hasPersonalEmail() |
247
|
|
|
{ |
248
|
3 |
|
$focus = new InboundEmail; |
249
|
3 |
|
$focus->retrieve_by_string_fields(array('group_id' => $this->id)); |
250
|
|
|
|
251
|
3 |
|
return !empty($focus->id); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/* Returns the User's private GUID; this is unassociated with the User's |
255
|
|
|
* actual GUID. It is used to secure file names that must be HTTP:// |
256
|
|
|
* accesible, but obfusicated. |
257
|
|
|
*/ |
258
|
1 |
|
function getUserPrivGuid() { |
259
|
1 |
|
$userPrivGuid = $this->getPreference('userPrivGuid', 'global', $this); |
260
|
1 |
|
if ($userPrivGuid) { |
261
|
1 |
|
return $userPrivGuid; |
262
|
|
|
} else { |
263
|
1 |
|
$this->setUserPrivGuid(); |
264
|
1 |
|
if (!isset ($_SESSION['setPrivGuid'])) { |
265
|
1 |
|
$_SESSION['setPrivGuid'] = true; |
266
|
1 |
|
$userPrivGuid = $this->getUserPrivGuid(); |
267
|
1 |
|
return $userPrivGuid; |
268
|
|
|
} else { |
269
|
|
|
sugar_die("Breaking Infinite Loop Condition: Could not setUserPrivGuid."); |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
|
274
|
2 |
|
function setUserPrivGuid() { |
275
|
2 |
|
$privGuid = create_guid(); |
276
|
|
|
//($name, $value, $nosession=0) |
277
|
2 |
|
$this->setPreference('userPrivGuid', $privGuid, 0, 'global', $this); |
278
|
2 |
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Interface for the User object to calling the UserPreference::setPreference() method in modules/UserPreferences/UserPreference.php |
282
|
|
|
* |
283
|
|
|
* @see UserPreference::setPreference() |
284
|
|
|
* |
285
|
|
|
* @param string $name Name of the preference to set |
286
|
|
|
* @param string $value Value to set preference to |
287
|
|
|
* @param null $nosession For BC, ignored |
288
|
|
|
* @param string $category Name of the category to retrieve |
289
|
|
|
*/ |
290
|
12 |
|
public function setPreference( |
291
|
|
|
$name, |
292
|
|
|
$value, |
293
|
|
|
$nosession = 0, |
294
|
|
|
$category = 'global' |
295
|
|
|
) |
296
|
|
|
{ |
297
|
|
|
// for BC |
298
|
12 |
|
if ( func_num_args() > 4 ) { |
299
|
3 |
|
$user = func_get_arg(4); |
300
|
3 |
|
$GLOBALS['log']->deprecated('User::setPreferences() should not be used statically.'); |
301
|
|
|
} |
302
|
|
|
else |
303
|
9 |
|
$user = $this; |
304
|
|
|
|
305
|
12 |
|
$user->_userPreferenceFocus->setPreference($name, $value, $category); |
306
|
12 |
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* Interface for the User object to calling the UserPreference::resetPreferences() method in modules/UserPreferences/UserPreference.php |
310
|
|
|
* |
311
|
|
|
* @see UserPreference::resetPreferences() |
312
|
|
|
* |
313
|
|
|
* @param string $category category to reset |
314
|
|
|
*/ |
315
|
1 |
|
public function resetPreferences( |
316
|
|
|
$category = null |
317
|
|
|
) |
318
|
|
|
{ |
319
|
|
|
// for BC |
320
|
1 |
|
if ( func_num_args() > 1 ) { |
321
|
|
|
$user = func_get_arg(1); |
322
|
|
|
$GLOBALS['log']->deprecated('User::resetPreferences() should not be used statically.'); |
323
|
|
|
} |
324
|
|
|
else |
325
|
1 |
|
$user = $this; |
326
|
|
|
|
327
|
1 |
|
$user->_userPreferenceFocus->resetPreferences($category); |
328
|
1 |
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* Interface for the User object to calling the UserPreference::savePreferencesToDB() method in modules/UserPreferences/UserPreference.php |
332
|
|
|
* |
333
|
|
|
* @see UserPreference::savePreferencesToDB() |
334
|
|
|
*/ |
335
|
4 |
|
public function savePreferencesToDB() |
336
|
|
|
{ |
337
|
|
|
// for BC |
338
|
4 |
|
if ( func_num_args() > 0 ) { |
339
|
|
|
$user = func_get_arg(0); |
340
|
|
|
$GLOBALS['log']->deprecated('User::savePreferencesToDB() should not be used statically.'); |
341
|
|
|
} |
342
|
|
|
else |
343
|
4 |
|
$user = $this; |
344
|
|
|
|
345
|
4 |
|
$user->_userPreferenceFocus->savePreferencesToDB(); |
346
|
4 |
|
} |
347
|
|
|
|
348
|
|
|
/** |
349
|
|
|
* Unconditionally reloads user preferences from the DB and updates the session |
350
|
|
|
* @param string $category name of the category to retreive, defaults to global scope |
351
|
|
|
* @return bool successful? |
352
|
|
|
*/ |
353
|
1 |
|
public function reloadPreferences($category = 'global') |
354
|
|
|
{ |
355
|
1 |
|
return $this->_userPreferenceFocus->reloadPreferences($category = 'global'); |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* Interface for the User object to calling the UserPreference::getUserDateTimePreferences() method in modules/UserPreferences/UserPreference.php |
360
|
|
|
* |
361
|
|
|
* @see UserPreference::getUserDateTimePreferences() |
362
|
|
|
* |
363
|
|
|
* @return array 'date' - date format for user ; 'time' - time format for user |
364
|
|
|
*/ |
365
|
6 |
|
public function getUserDateTimePreferences() |
366
|
|
|
{ |
367
|
|
|
// for BC |
368
|
6 |
|
if ( func_num_args() > 0 ) { |
369
|
|
|
$user = func_get_arg(0); |
370
|
|
|
$GLOBALS['log']->deprecated('User::getUserDateTimePreferences() should not be used statically.'); |
371
|
|
|
} |
372
|
|
|
else |
373
|
6 |
|
$user = $this; |
374
|
|
|
|
375
|
6 |
|
return $user->_userPreferenceFocus->getUserDateTimePreferences(); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
/** |
379
|
|
|
* Interface for the User object to calling the UserPreference::loadPreferences() method in modules/UserPreferences/UserPreference.php |
380
|
|
|
* |
381
|
|
|
* @see UserPreference::loadPreferences() |
382
|
|
|
* |
383
|
|
|
* @param string $category name of the category to retreive, defaults to global scope |
384
|
|
|
* @return bool successful? |
385
|
|
|
*/ |
386
|
10 |
|
public function loadPreferences( |
387
|
|
|
$category = 'global' |
388
|
|
|
) |
389
|
|
|
{ |
390
|
|
|
// for BC |
391
|
10 |
|
if ( func_num_args() > 1 ) { |
392
|
|
|
$user = func_get_arg(1); |
393
|
|
|
$GLOBALS['log']->deprecated('User::loadPreferences() should not be used statically.'); |
394
|
|
|
} |
395
|
|
|
else |
396
|
10 |
|
$user = $this; |
397
|
|
|
|
398
|
10 |
|
return $user->_userPreferenceFocus->loadPreferences($category); |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Interface for the User object to calling the UserPreference::setPreference() method in modules/UserPreferences/UserPreference.php |
403
|
|
|
* |
404
|
|
|
* @see UserPreference::getPreference() |
405
|
|
|
* |
406
|
|
|
* @param string $name name of the preference to retreive |
407
|
|
|
* @param string $category name of the category to retreive, defaults to global scope |
408
|
|
|
* @return mixed the value of the preference (string, array, int etc) |
409
|
|
|
*/ |
410
|
212 |
|
public function getPreference( |
411
|
|
|
$name, |
412
|
|
|
$category = 'global' |
413
|
|
|
) |
414
|
|
|
{ |
415
|
|
|
// for BC |
416
|
212 |
|
if ( func_num_args() > 2 ) { |
417
|
4 |
|
$user = func_get_arg(2); |
418
|
4 |
|
$GLOBALS['log']->deprecated('User::getPreference() should not be used statically.'); |
419
|
|
|
} |
420
|
|
|
else |
421
|
212 |
|
$user = $this; |
422
|
|
|
|
423
|
212 |
|
return $user->_userPreferenceFocus->getPreference($name, $category); |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
/** |
427
|
|
|
* incrementETag |
428
|
|
|
* |
429
|
|
|
* This function increments any ETag seed needed for a particular user's |
430
|
|
|
* UI. For example, if the user changes their theme, the ETag seed for the |
431
|
|
|
* main menu needs to be updated, so you call this function with the seed name |
432
|
|
|
* to do so: |
433
|
|
|
* |
434
|
|
|
* UserPreference::incrementETag("mainMenuETag"); |
435
|
|
|
* |
436
|
|
|
* @param string $tag ETag seed name. |
437
|
|
|
* @return nothing |
438
|
|
|
*/ |
439
|
1 |
|
public function incrementETag($tag){ |
440
|
1 |
|
$val = $this->getETagSeed($tag); |
441
|
1 |
|
if($val == 2147483648){ |
442
|
|
|
$val = 0; |
443
|
|
|
} |
444
|
1 |
|
$val++; |
445
|
1 |
|
$this->setPreference($tag, $val, 0, "ETag"); |
446
|
1 |
|
} |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* getETagSeed |
450
|
|
|
* |
451
|
|
|
* This function is a wrapper to encapsulate getting the ETag seed and |
452
|
|
|
* making sure it's sanitized for use in the app. |
453
|
|
|
* |
454
|
|
|
* @param string $tag ETag seed name. |
455
|
|
|
* @return integer numeric value of the seed |
456
|
|
|
*/ |
457
|
2 |
|
public function getETagSeed($tag){ |
458
|
2 |
|
$val = $this->getPreference($tag, "ETag"); |
459
|
2 |
|
if($val == null){ |
460
|
2 |
|
$val = 0; |
461
|
|
|
} |
462
|
2 |
|
return $val; |
463
|
|
|
} |
464
|
|
|
|
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* Get WHERE clause that fetches all users counted for licensing purposes |
468
|
|
|
* @return string |
469
|
|
|
*/ |
470
|
4 |
|
public static function getLicensedUsersWhere() |
471
|
|
|
{ |
472
|
4 |
|
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"; |
473
|
|
|
return "1<>1"; |
|
|
|
|
474
|
|
|
} |
475
|
|
|
|
476
|
3 |
|
function save($check_notify = false) { |
477
|
3 |
|
$isUpdate = !empty($this->id) && !$this->new_with_id; |
478
|
|
|
|
479
|
|
|
|
480
|
3 |
|
$query = "SELECT count(id) as total from users WHERE ".self::getLicensedUsersWhere(); |
481
|
|
|
|
482
|
|
|
|
483
|
|
|
// is_group & portal should be set to 0 by default |
484
|
3 |
|
if (!isset($this->is_group)) { |
485
|
2 |
|
$this->is_group = 0; |
486
|
|
|
} |
487
|
3 |
|
if (!isset($this->portal_only)) { |
488
|
|
|
$this->portal_only = 0; |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
// wp: do not save user_preferences in this table, see user_preferences module |
492
|
3 |
|
$this->user_preferences = ''; |
493
|
|
|
|
494
|
|
|
// if this is an admin user, do not allow is_group or portal_only flag to be set. |
495
|
3 |
|
if ($this->is_admin) { |
496
|
1 |
|
$this->is_group = 0; |
497
|
1 |
|
$this->portal_only = 0; |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
|
501
|
|
|
// set some default preferences when creating a new user |
502
|
3 |
|
$setNewUserPreferences = empty($this->id) || !empty($this->new_with_id); |
503
|
|
|
|
504
|
|
|
|
505
|
3 |
|
parent::save($check_notify); |
506
|
|
|
|
507
|
|
|
|
508
|
|
|
// set some default preferences when creating a new user |
509
|
3 |
|
if ( $setNewUserPreferences ) { |
510
|
2 |
|
if(!$this->getPreference('calendar_publish_key')) { |
511
|
2 |
|
$this->setPreference('calendar_publish_key', create_guid()); |
512
|
|
|
} |
513
|
|
|
} |
514
|
|
|
|
515
|
3 |
|
$this->savePreferencesToDB(); |
516
|
3 |
|
return $this->id; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
/** |
520
|
|
|
* @return boolean true if the user is a member of the role_name, false otherwise |
521
|
|
|
* @param string $role_name - Must be the exact name of the acl_role |
522
|
|
|
* @param string $user_id - The user id to check for the role membership, empty string if current user |
523
|
|
|
* @desc Determine whether or not a user is a member of an ACL Role. This function caches the |
524
|
|
|
* results in the session or to prevent running queries after the first time executed. |
525
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. |
526
|
|
|
* All Rights Reserved.. |
527
|
|
|
* Contributor(s): ______________________________________.. |
528
|
|
|
*/ |
529
|
1 |
|
function check_role_membership($role_name, $user_id = ''){ |
530
|
|
|
|
531
|
1 |
|
global $current_user; |
532
|
|
|
|
533
|
1 |
|
if(empty($user_id)) |
534
|
1 |
|
$user_id = $current_user->id; |
535
|
|
|
|
536
|
|
|
// Check the Sugar External Cache to see if this users memberships were cached |
537
|
1 |
|
$role_array = sugar_cache_retrieve("RoleMemberships_".$user_id); |
538
|
|
|
|
539
|
|
|
// If we are pulling the roles for the current user |
540
|
1 |
|
if($user_id == $current_user->id){ |
541
|
|
|
// If the Session doesn't contain the values |
542
|
1 |
|
if(!isset($_SESSION['role_memberships'])){ |
543
|
|
|
// This means the external cache already had it loaded |
544
|
1 |
|
if(!empty($role_array)) |
545
|
|
|
$_SESSION['role_memberships'] = $role_array; |
546
|
|
|
else{ |
547
|
1 |
|
$_SESSION['role_memberships'] = ACLRole::getUserRoleNames($user_id); |
548
|
1 |
|
$role_array = $_SESSION['role_memberships']; |
549
|
|
|
} |
550
|
|
|
} |
551
|
|
|
// else the session had the values, so we assign to the role array |
552
|
|
|
else{ |
553
|
1 |
|
$role_array = $_SESSION['role_memberships']; |
554
|
|
|
} |
555
|
|
|
} |
556
|
|
|
else{ |
557
|
|
|
// If the external cache didn't contain the values, we get them and put them in cache |
558
|
1 |
|
if(!$role_array){ |
559
|
1 |
|
$role_array = ACLRole::getUserRoleNames($user_id); |
560
|
1 |
|
sugar_cache_put("RoleMemberships_".$user_id, $role_array); |
|
|
|
|
561
|
|
|
} |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
// If the role doesn't exist in the list of the user's roles |
565
|
1 |
|
if(!empty($role_array) && in_array($role_name, $role_array)) |
566
|
|
|
return true; |
567
|
|
|
else |
568
|
1 |
|
return false; |
569
|
|
|
} |
570
|
|
|
|
571
|
6 |
|
function get_summary_text() { |
572
|
|
|
//$this->_create_proper_name_field(); |
573
|
6 |
|
return $this->name; |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
/** |
577
|
|
|
* @deprecated |
578
|
|
|
* @param string $user_name - Must be non null and at least 2 characters |
|
|
|
|
579
|
|
|
* @param string $user_password - Must be non null and at least 1 character. |
580
|
|
|
* @desc Take an unencrypted username and password and return the encrypted password |
581
|
|
|
* @return string encrypted password for storage in DB and comparison against DB password. |
582
|
|
|
*/ |
583
|
1 |
|
function encrypt_password($user_password) |
584
|
|
|
{ |
585
|
|
|
// encrypt the password. |
586
|
1 |
|
$salt = substr($this->user_name, 0, 2); |
587
|
1 |
|
$encrypted_password = crypt($user_password, $salt); |
588
|
|
|
|
589
|
1 |
|
return $encrypted_password; |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* Authenicates the user; returns true if successful |
594
|
|
|
* |
595
|
|
|
* @param string $password MD5-encoded password |
596
|
|
|
* @return bool |
597
|
|
|
*/ |
598
|
1 |
|
public function authenticate_user($password) |
599
|
|
|
{ |
600
|
1 |
|
$row = self::findUserPassword($this->user_name, $password); |
601
|
1 |
|
if(empty($row)) { |
602
|
1 |
|
return false; |
603
|
|
|
} else { |
604
|
1 |
|
$this->id = $row['id']; |
605
|
1 |
|
return true; |
606
|
|
|
} |
607
|
|
|
} |
608
|
|
|
|
609
|
|
|
/** |
610
|
|
|
* retrieves an User bean |
611
|
|
|
* preformat name & full_name attribute with first/last |
612
|
|
|
* loads User's preferences |
613
|
|
|
* |
614
|
|
|
* @param string id ID of the User |
615
|
|
|
* @param bool encode encode the result |
616
|
|
|
* @return object User bean |
617
|
|
|
* @return null null if no User found |
618
|
|
|
*/ |
619
|
52 |
|
function retrieve($id = -1, $encode = true, $deleted = true) { |
620
|
52 |
|
$ret = parent::retrieve($id, $encode, $deleted); |
621
|
52 |
|
if ($ret) { |
622
|
48 |
|
if (isset ($_SESSION)) { |
623
|
4 |
|
$this->loadPreferences(); |
624
|
|
|
} |
625
|
|
|
} |
626
|
52 |
|
return $ret; |
627
|
|
|
} |
628
|
|
|
|
629
|
1 |
|
function retrieve_by_email_address($email) { |
630
|
|
|
|
631
|
1 |
|
$email1= strtoupper($email); |
632
|
|
|
$q=<<<EOQ |
633
|
|
|
|
634
|
|
|
select id from users where id in ( SELECT er.bean_id AS id FROM email_addr_bean_rel er, |
635
|
|
|
email_addresses ea WHERE ea.id = er.email_address_id |
636
|
1 |
|
AND ea.deleted = 0 AND er.deleted = 0 AND er.bean_module = 'Users' AND email_address_caps IN ('{$email1}') ) |
637
|
|
|
EOQ; |
638
|
|
|
|
639
|
|
|
|
640
|
1 |
|
$res=$this->db->query($q); |
641
|
1 |
|
$row=$this->db->fetchByAssoc($res); |
642
|
|
|
|
643
|
1 |
|
if (!empty($row['id'])) { |
644
|
1 |
|
return $this->retrieve($row['id']); |
645
|
|
|
} |
646
|
1 |
|
return ''; |
647
|
|
|
} |
648
|
|
|
|
649
|
156 |
|
function bean_implements($interface) { |
650
|
|
|
switch($interface){ |
651
|
156 |
|
case 'ACL':return true; |
|
|
|
|
652
|
|
|
} |
653
|
2 |
|
return false; |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
|
657
|
|
|
/** |
658
|
|
|
* Load a user based on the user_name in $this |
659
|
|
|
* @param string $user_password Password |
660
|
|
|
* @param bool $password_encoded Is password md5-encoded or plain text? |
661
|
|
|
* @return -- this if load was successul and null if load failed. |
|
|
|
|
662
|
|
|
*/ |
663
|
1 |
|
function load_user($user_password, $password_encoded = false) |
664
|
|
|
{ |
665
|
1 |
|
global $login_error; |
666
|
1 |
|
unset($GLOBALS['login_error']); |
667
|
1 |
|
if(isset ($_SESSION['loginattempts'])) { |
668
|
|
|
$_SESSION['loginattempts'] += 1; |
669
|
|
|
} else { |
670
|
1 |
|
$_SESSION['loginattempts'] = 1; |
671
|
|
|
} |
672
|
1 |
|
if($_SESSION['loginattempts'] > 5) { |
673
|
|
|
$GLOBALS['log']->fatal('SECURITY: '.$this->user_name.' has attempted to login '.$_SESSION['loginattempts'].' times from IP address: '.$_SERVER['REMOTE_ADDR'].'.'); |
674
|
|
|
return null; |
675
|
|
|
} |
676
|
|
|
|
677
|
1 |
|
$GLOBALS['log']->debug("Starting user load for $this->user_name"); |
678
|
|
|
|
679
|
1 |
|
if (!isset ($this->user_name) || $this->user_name == "" || !isset ($user_password) || $user_password == "") |
680
|
|
|
return null; |
681
|
|
|
|
682
|
1 |
|
if(!$password_encoded) { |
683
|
1 |
|
$user_password = md5($user_password); |
684
|
|
|
} |
685
|
1 |
|
$row = self::findUserPassword($this->user_name, $user_password); |
686
|
1 |
|
if(empty($row) || !empty ($GLOBALS['login_error'])) { |
687
|
|
|
$GLOBALS['log']->fatal('SECURITY: User authentication for '.$this->user_name.' failed - could not Load User from Database'); |
688
|
|
|
return null; |
689
|
|
|
} |
690
|
|
|
|
691
|
|
|
// now fill in the fields. |
692
|
1 |
|
$this->loadFromRow($row); |
693
|
1 |
|
$this->loadPreferences(); |
694
|
|
|
|
695
|
1 |
|
if ($this->status != "Inactive") |
696
|
1 |
|
$this->authenticated = true; |
697
|
|
|
|
698
|
1 |
|
unset ($_SESSION['loginattempts']); |
699
|
1 |
|
return $this; |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
/** |
703
|
|
|
* Generate a new hash from plaintext password |
704
|
|
|
* @param string $password |
705
|
|
|
*/ |
706
|
1 |
|
public static function getPasswordHash($password) |
707
|
|
|
{ |
708
|
1 |
|
if(!defined('CRYPT_MD5') || !constant('CRYPT_MD5')) { |
709
|
|
|
// does not support MD5 crypt - leave as is |
710
|
|
|
if(defined('CRYPT_EXT_DES') && constant('CRYPT_EXT_DES')) { |
711
|
|
|
return crypt(strtolower(md5($password)), |
712
|
|
|
"_.012".substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), -4)); |
713
|
|
|
} |
714
|
|
|
// plain crypt cuts password to 8 chars, which is not enough |
715
|
|
|
// fall back to old md5 |
716
|
|
|
return strtolower(md5($password)); |
717
|
|
|
} |
718
|
1 |
|
return @crypt(strtolower(md5($password))); |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
/** |
722
|
|
|
* Check that password matches existing hash |
723
|
|
|
* @param string $password Plaintext password |
724
|
|
|
* @param string $user_hash DB hash |
725
|
|
|
*/ |
726
|
1 |
|
public static function checkPassword($password, $user_hash) |
727
|
|
|
{ |
728
|
1 |
|
return self::checkPasswordMD5(md5($password), $user_hash); |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
/** |
732
|
|
|
* Check that md5-encoded password matches existing hash |
733
|
|
|
* @param string $password MD5-encoded password |
|
|
|
|
734
|
|
|
* @param string $user_hash DB hash |
735
|
|
|
* @return bool Match or not? |
736
|
|
|
*/ |
737
|
3 |
|
public static function checkPasswordMD5($password_md5, $user_hash) |
738
|
|
|
{ |
739
|
3 |
|
if(empty($user_hash)) return false; |
740
|
3 |
|
if($user_hash[0] != '$' && strlen($user_hash) == 32) { |
741
|
|
|
// Old way - just md5 password |
742
|
|
|
return strtolower($password_md5) == $user_hash; |
743
|
|
|
} |
744
|
3 |
|
return crypt(strtolower($password_md5), $user_hash) == $user_hash; |
745
|
|
|
} |
746
|
|
|
|
747
|
|
|
/** |
748
|
|
|
* Find user with matching password |
749
|
|
|
* @param string $name Username |
750
|
|
|
* @param string $password MD5-encoded password |
751
|
|
|
* @param string $where Limiting query |
752
|
|
|
* @return the matching User of false if not found |
753
|
|
|
*/ |
754
|
1 |
|
public static function findUserPassword($name, $password, $where = '') |
755
|
|
|
{ |
756
|
1 |
|
global $db; |
757
|
1 |
|
$name = $db->quote($name); |
758
|
1 |
|
$query = "SELECT * from users where user_name='$name'"; |
759
|
1 |
|
if(!empty($where)) { |
760
|
|
|
$query .= " AND $where"; |
761
|
|
|
} |
762
|
1 |
|
$result = $db->limitQuery($query,0,1,false); |
763
|
1 |
|
if(!empty($result)) { |
764
|
1 |
|
$row = $db->fetchByAssoc($result); |
765
|
1 |
|
if(self::checkPasswordMD5($password, $row['user_hash'])) { |
766
|
1 |
|
return $row; |
767
|
|
|
} |
768
|
|
|
} |
769
|
1 |
|
return false; |
770
|
|
|
} |
771
|
|
|
|
772
|
|
|
/** |
773
|
|
|
* Sets new password and resets password expiration timers |
774
|
|
|
* @param string $new_password |
775
|
|
|
*/ |
776
|
1 |
|
public function setNewPassword($new_password, $system_generated = '0') |
777
|
|
|
{ |
778
|
1 |
|
$user_hash = self::getPasswordHash($new_password); |
779
|
1 |
|
$this->setPreference('loginexpiration','0'); |
780
|
1 |
|
$this->setPreference('lockout',''); |
781
|
1 |
|
$this->setPreference('loginfailed','0'); |
782
|
1 |
|
$this->savePreferencesToDB(); |
783
|
|
|
//set new password |
784
|
1 |
|
$now = TimeDate::getInstance()->nowDb(); |
785
|
1 |
|
$query = "UPDATE $this->table_name SET user_hash='$user_hash', system_generated_password='$system_generated', pwd_last_changed='$now' where id='$this->id'"; |
786
|
1 |
|
$this->db->query($query, true, "Error setting new password for $this->user_name: "); |
787
|
1 |
|
$_SESSION['hasExpiredPassword'] = '0'; |
788
|
1 |
|
} |
789
|
|
|
|
790
|
|
|
/** |
791
|
|
|
* Verify that the current password is correct and write the new password to the DB. |
792
|
|
|
* |
793
|
|
|
* @param string $user_password - Must be non null and at least 1 character. |
794
|
|
|
* @param string $new_password - Must be non null and at least 1 character. |
795
|
|
|
* @param string $system_generated |
796
|
|
|
* @return boolean - If passwords pass verification and query succeeds, return true, else return false. |
797
|
|
|
*/ |
798
|
1 |
|
function change_password($user_password, $new_password, $system_generated = '0') |
799
|
|
|
{ |
800
|
1 |
|
global $mod_strings; |
801
|
1 |
|
global $current_user; |
802
|
1 |
|
$GLOBALS['log']->debug("Starting password change for $this->user_name"); |
803
|
|
|
|
804
|
1 |
|
if (!isset ($new_password) || $new_password == "") { |
805
|
|
|
$this->error_string = $mod_strings['ERR_PASSWORD_CHANGE_FAILED_1'].$current_user->user_name.$mod_strings['ERR_PASSWORD_CHANGE_FAILED_2']; |
806
|
|
|
return false; |
807
|
|
|
} |
808
|
|
|
|
809
|
|
|
|
810
|
|
|
//check old password current user is not an admin or current user is an admin editing themselves |
811
|
1 |
|
if (!$current_user->isAdminForModule('Users') || ($current_user->isAdminForModule('Users') && ($current_user->id == $this->id))) { |
812
|
|
|
//check old password first |
813
|
1 |
|
$row = self::findUserPassword($this->user_name, md5($user_password)); |
814
|
1 |
|
if (empty($row)) { |
815
|
|
|
$GLOBALS['log']->warn("Incorrect old password for ".$this->user_name.""); |
816
|
|
|
$this->error_string = $mod_strings['ERR_PASSWORD_INCORRECT_OLD_1'].$this->user_name.$mod_strings['ERR_PASSWORD_INCORRECT_OLD_2']; |
817
|
|
|
return false; |
818
|
|
|
} |
819
|
|
|
} |
820
|
|
|
|
821
|
1 |
|
$this->setNewPassword($new_password, $system_generated); |
822
|
1 |
|
return true; |
823
|
|
|
} |
824
|
|
|
|
825
|
|
|
|
826
|
1 |
|
function is_authenticated() { |
827
|
1 |
|
return $this->authenticated; |
828
|
|
|
} |
829
|
|
|
|
830
|
5 |
|
function fill_in_additional_list_fields() { |
831
|
5 |
|
$this->fill_in_additional_detail_fields(); |
832
|
5 |
|
} |
833
|
|
|
|
834
|
54 |
|
function fill_in_additional_detail_fields() { |
835
|
|
|
// jmorais@dri Bug #56269 |
836
|
54 |
|
parent::fill_in_additional_detail_fields(); |
837
|
|
|
// ~jmorais@dri |
838
|
54 |
|
global $locale; |
839
|
|
|
|
840
|
54 |
|
$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"; |
841
|
54 |
|
$result = $this->db->query($query, true, "Error filling in additional detail fields"); |
842
|
|
|
|
843
|
54 |
|
$row = $this->db->fetchByAssoc($result); |
844
|
|
|
|
845
|
54 |
|
if ($row != null) { |
846
|
|
|
$this->reports_to_name = stripslashes($row['first_name'].' '.$row['last_name']); |
847
|
|
|
} else { |
848
|
54 |
|
$this->reports_to_name = ''; |
849
|
|
|
} |
850
|
|
|
|
851
|
|
|
|
852
|
54 |
|
$this->_create_proper_name_field(); |
853
|
54 |
|
} |
854
|
|
|
|
855
|
2 |
|
public function retrieve_user_id( |
856
|
|
|
$user_name |
857
|
|
|
) |
858
|
|
|
{ |
859
|
2 |
|
$userFocus = new User; |
860
|
2 |
|
$userFocus->retrieve_by_string_fields(array('user_name'=>$user_name)); |
861
|
2 |
|
if ( empty($userFocus->id) ) |
862
|
1 |
|
return false; |
863
|
|
|
|
864
|
1 |
|
return $userFocus->id; |
865
|
|
|
} |
866
|
|
|
|
867
|
|
|
/** |
868
|
|
|
* @return -- returns a list of all users in the system. |
|
|
|
|
869
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. |
870
|
|
|
* All Rights Reserved.. |
871
|
|
|
* Contributor(s): ______________________________________.. |
872
|
|
|
*/ |
873
|
1 |
|
function verify_data($ieVerified=true) { |
874
|
1 |
|
global $mod_strings, $current_user; |
875
|
1 |
|
$verified = TRUE; |
876
|
|
|
|
877
|
1 |
|
if (!empty ($this->id)) { |
878
|
|
|
// Make sure the user doesn't report to themselves. |
879
|
1 |
|
$reports_to_self = 0; |
880
|
1 |
|
$check_user = $this->reports_to_id; |
881
|
1 |
|
$already_seen_list = array (); |
882
|
1 |
|
while (!empty ($check_user)) { |
883
|
|
|
if (isset ($already_seen_list[$check_user])) { |
884
|
|
|
// This user doesn't actually report to themselves |
885
|
|
|
// But someone above them does. |
886
|
|
|
$reports_to_self = 1; |
887
|
|
|
break; |
888
|
|
|
} |
889
|
|
|
if ($check_user == $this->id) { |
890
|
|
|
$reports_to_self = 1; |
891
|
|
|
break; |
892
|
|
|
} |
893
|
|
|
$already_seen_list[$check_user] = 1; |
894
|
|
|
$query = "SELECT reports_to_id FROM users WHERE id='".$this->db->quote($check_user)."'"; |
895
|
|
|
$result = $this->db->query($query, true, "Error checking for reporting-loop"); |
896
|
|
|
$row = $this->db->fetchByAssoc($result); |
897
|
|
|
echo ("fetched: ".$row['reports_to_id']." from ".$check_user."<br>"); |
898
|
|
|
$check_user = $row['reports_to_id']; |
899
|
|
|
} |
900
|
|
|
|
901
|
1 |
|
if ($reports_to_self == 1) { |
902
|
|
|
$this->error_string .= $mod_strings['ERR_REPORT_LOOP']; |
903
|
|
|
$verified = FALSE; |
904
|
|
|
} |
905
|
|
|
} |
906
|
|
|
|
907
|
1 |
|
$query = "SELECT user_name from users where user_name='$this->user_name' AND deleted=0"; |
908
|
1 |
|
if(!empty($this->id))$query .= " AND id<>'$this->id'"; |
909
|
1 |
|
$result = $this->db->query($query, true, "Error selecting possible duplicate users: "); |
910
|
1 |
|
$dup_users = $this->db->fetchByAssoc($result); |
911
|
|
|
|
912
|
1 |
|
if (!empty($dup_users)) { |
913
|
|
|
$this->error_string .= $mod_strings['ERR_USER_NAME_EXISTS_1'].$this->user_name.$mod_strings['ERR_USER_NAME_EXISTS_2']; |
914
|
|
|
$verified = FALSE; |
915
|
|
|
} |
916
|
|
|
|
917
|
1 |
|
if (is_admin($current_user)) { |
918
|
|
|
$remaining_admins = $this->db->getOne("SELECT COUNT(*) as c from users where is_admin = 1 AND deleted=0"); |
919
|
|
|
|
920
|
|
|
if (($remaining_admins <= 1) && ($this->is_admin != '1') && ($this->id == $current_user->id)) { |
921
|
|
|
$GLOBALS['log']->debug("Number of remaining administrator accounts: {$remaining_admins}"); |
922
|
|
|
$this->error_string .= $mod_strings['ERR_LAST_ADMIN_1'].$this->user_name.$mod_strings['ERR_LAST_ADMIN_2']; |
923
|
|
|
$verified = FALSE; |
924
|
|
|
} |
925
|
|
|
} |
926
|
|
|
/////////////////////////////////////////////////////////////////////// |
927
|
|
|
//// InboundEmail verification failure |
928
|
1 |
|
if(!$ieVerified) { |
929
|
1 |
|
$verified = false; |
930
|
1 |
|
$this->error_string .= '<br />'.$mod_strings['ERR_EMAIL_NO_OPTS']; |
931
|
|
|
} |
932
|
|
|
|
933
|
1 |
|
return $verified; |
934
|
|
|
} |
935
|
|
|
|
936
|
4 |
|
function get_list_view_data() { |
937
|
|
|
|
938
|
4 |
|
global $mod_strings; |
939
|
|
|
|
940
|
4 |
|
$user_fields = parent::get_list_view_data(); |
941
|
|
|
|
942
|
4 |
|
if ($this->is_admin) |
943
|
3 |
|
$user_fields['IS_ADMIN_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',$mod_strings['LBL_CHECKMARK']); |
944
|
3 |
|
elseif (!$this->is_admin) $user_fields['IS_ADMIN'] = ''; |
945
|
4 |
|
if ($this->is_group) |
946
|
|
|
$user_fields['IS_GROUP_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',$mod_strings['LBL_CHECKMARK']); |
947
|
|
|
else |
948
|
4 |
|
$user_fields['IS_GROUP_IMAGE'] = ''; |
949
|
|
|
|
950
|
|
|
|
951
|
4 |
|
if ($this->is_admin) { |
952
|
3 |
|
$user_fields['IS_ADMIN_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',translate('LBL_CHECKMARK', 'Users')); |
953
|
3 |
|
} elseif (!$this->is_admin) { |
954
|
3 |
|
$user_fields['IS_ADMIN'] = ''; |
955
|
|
|
} |
956
|
|
|
|
957
|
4 |
|
if ($this->is_group) { |
958
|
|
|
$user_fields['IS_GROUP_IMAGE'] = SugarThemeRegistry::current()->getImage('check_inline', '',null,null,'.gif',translate('LBL_CHECKMARK', 'Users')); |
959
|
|
|
} else { |
960
|
4 |
|
$user_fields['NAME'] = empty ($this->name) ? '' : $this->name; |
961
|
|
|
} |
962
|
|
|
|
963
|
4 |
|
$user_fields['REPORTS_TO_NAME'] = $this->reports_to_name; |
964
|
|
|
|
965
|
|
|
|
966
|
4 |
|
return $user_fields; |
967
|
|
|
} |
968
|
|
|
|
969
|
1 |
|
function list_view_parse_additional_sections(&$list_form) { |
970
|
1 |
|
return $list_form; |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
|
974
|
|
|
|
975
|
|
|
|
976
|
|
|
/** |
977
|
|
|
* getAllUsers |
978
|
|
|
* |
979
|
|
|
* Returns all active and inactive users |
980
|
|
|
* @return Array of all users in the system |
981
|
|
|
*/ |
982
|
|
|
|
983
|
1 |
|
public static function getAllUsers() |
984
|
|
|
{ |
985
|
1 |
|
$active_users = get_user_array(FALSE); |
986
|
1 |
|
$inactive_users = get_user_array(FALSE, "Inactive"); |
987
|
1 |
|
$result = $active_users + $inactive_users; |
988
|
1 |
|
asort($result); |
989
|
1 |
|
return $result; |
990
|
|
|
} |
991
|
|
|
|
992
|
|
|
/** |
993
|
|
|
* getActiveUsers |
994
|
|
|
* |
995
|
|
|
* Returns all active users |
996
|
|
|
* @return Array of active users in the system |
997
|
|
|
*/ |
998
|
|
|
|
999
|
1 |
|
public static function getActiveUsers() |
1000
|
|
|
{ |
1001
|
1 |
|
$active_users = get_user_array(FALSE); |
1002
|
1 |
|
asort($active_users); |
1003
|
1 |
|
return $active_users; |
1004
|
|
|
} |
1005
|
|
|
|
1006
|
|
|
|
1007
|
|
|
|
1008
|
1 |
|
function create_export_query($order_by, $where, $relate_link_join = '') { |
1009
|
1 |
|
include('modules/Users/field_arrays.php'); |
1010
|
|
|
|
1011
|
1 |
|
$cols = ''; |
1012
|
1 |
|
foreach($fields_array['User']['export_fields'] as $field) { |
1013
|
1 |
|
$cols .= (empty($cols)) ? '' : ', '; |
1014
|
1 |
|
$cols .= $field; |
1015
|
|
|
} |
1016
|
|
|
|
1017
|
1 |
|
$query = "SELECT {$cols} FROM users "; |
1018
|
|
|
|
1019
|
1 |
|
$where_auto = " users.deleted = 0"; |
1020
|
|
|
|
1021
|
1 |
|
if ($where != "") |
1022
|
1 |
|
$query .= " WHERE $where AND ".$where_auto; |
1023
|
|
|
else |
1024
|
1 |
|
$query .= " WHERE ".$where_auto; |
1025
|
|
|
|
1026
|
|
|
// admin for module user is not be able to export a super-admin |
1027
|
1 |
|
global $current_user; |
1028
|
1 |
|
if(!$current_user->is_admin){ |
1029
|
1 |
|
$query .= " AND users.is_admin=0"; |
1030
|
|
|
} |
1031
|
|
|
|
1032
|
1 |
|
if ($order_by != "") |
1033
|
1 |
|
$query .= " ORDER BY $order_by"; |
1034
|
|
|
else |
1035
|
1 |
|
$query .= " ORDER BY users.user_name"; |
1036
|
|
|
|
1037
|
1 |
|
return $query; |
1038
|
|
|
} |
1039
|
|
|
|
1040
|
|
|
/** Returns a list of the associated users |
1041
|
|
|
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.. |
1042
|
|
|
* All Rights Reserved.. |
1043
|
|
|
* Contributor(s): ______________________________________.. |
1044
|
|
|
*/ |
1045
|
1 |
|
function get_meetings() { |
1046
|
|
|
// First, get the list of IDs. |
1047
|
1 |
|
$query = "SELECT meeting_id as id from meetings_users where user_id='$this->id' AND deleted=0"; |
1048
|
1 |
|
return $this->build_related_list($query, new Meeting()); |
1049
|
|
|
} |
1050
|
|
|
function get_calls() { |
1051
|
|
|
// First, get the list of IDs. |
1052
|
|
|
$query = "SELECT call_id as id from calls_users where user_id='$this->id' AND deleted=0"; |
1053
|
|
|
return $this->build_related_list($query, new Call()); |
1054
|
|
|
} |
1055
|
|
|
|
1056
|
|
|
/** |
1057
|
|
|
* generates Javascript to display I-E mail counts, both personal and group |
1058
|
|
|
*/ |
1059
|
1 |
|
function displayEmailCounts() { |
1060
|
1 |
|
global $theme; |
1061
|
1 |
|
$new = translate('LBL_NEW', 'Emails'); |
1062
|
1 |
|
$default = 'index.php?module=Emails&action=ListView&assigned_user_id='.$this->id; |
1063
|
1 |
|
$count = ''; |
1064
|
1 |
|
$verts = array('Love', 'Links', 'Pipeline', 'RipCurl', 'SugarLite'); |
1065
|
|
|
|
1066
|
1 |
|
if($this->hasPersonalEmail()) { |
1067
|
|
|
$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\''); |
1068
|
|
|
$a = $this->db->fetchByAssoc($r); |
1069
|
|
|
if(in_array($theme, $verts)) { |
1070
|
|
|
$count .= '<br />'; |
1071
|
|
|
} else { |
1072
|
|
|
$count .= ' '; |
1073
|
|
|
} |
1074
|
|
|
$count .= '<a href='.$default.'&type=inbound>'.translate('LBL_LIST_TITLE_MY_INBOX', 'Emails').': ('.$a['c'].' '.$new.')</a>'; |
1075
|
|
|
|
1076
|
|
|
if(!in_array($theme, $verts)) { |
1077
|
|
|
$count .= ' - '; |
1078
|
|
|
} |
1079
|
|
|
} |
1080
|
|
|
|
1081
|
1 |
|
$r = $this->db->query('SELECT id FROM users WHERE users.is_group = 1 AND deleted = 0'); |
1082
|
1 |
|
$groupIds = ''; |
1083
|
1 |
|
$groupNew = ''; |
1084
|
1 |
|
while($a = $this->db->fetchByAssoc($r)) { |
1085
|
|
|
if($groupIds != '') {$groupIds .= ', ';} |
1086
|
|
|
$groupIds .= "'".$a['id']."'"; |
1087
|
|
|
} |
1088
|
|
|
|
1089
|
1 |
|
$total = 0; |
1090
|
1 |
|
if(strlen($groupIds) > 0) { |
1091
|
|
|
$groupQuery = 'SELECT count(*) AS c FROM emails '; |
1092
|
|
|
$groupQuery .= ' WHERE emails.deleted=0 AND emails.assigned_user_id IN ('.$groupIds.') AND emails.type = \'inbound\' AND emails.status = \'unread\''; |
1093
|
|
|
$r = $this->db->query($groupQuery); |
1094
|
|
|
if(is_resource($r)) { |
1095
|
|
|
$a = $this->db->fetchByAssoc($r); |
1096
|
|
|
if($a['c'] > 0) { |
1097
|
|
|
$total = $a['c']; |
1098
|
|
|
} |
1099
|
|
|
} |
1100
|
|
|
} |
1101
|
1 |
|
if(in_array($theme, $verts)) $count .= '<br />'; |
1102
|
1 |
|
if(empty($count)) $count .= ' '; |
1103
|
1 |
|
$count .= '<a href=index.php?module=Emails&action=ListViewGroup>'.translate('LBL_LIST_TITLE_GROUP_INBOX', 'Emails').': ('.$total.' '.$new.')</a>'; |
1104
|
|
|
|
1105
|
1 |
|
$out = '<script type="text/javascript" language="Javascript">'; |
1106
|
1 |
|
$out .= 'var welcome = document.getElementById("welcome");'; |
1107
|
1 |
|
$out .= 'var welcomeContent = welcome.innerHTML;'; |
1108
|
1 |
|
$out .= 'welcome.innerHTML = welcomeContent + "'.$count.'";'; |
1109
|
1 |
|
$out .= '</script>'; |
1110
|
|
|
|
1111
|
1 |
|
echo $out; |
1112
|
1 |
|
} |
1113
|
|
|
|
1114
|
1 |
|
function getPreferredEmail() { |
1115
|
1 |
|
$ret = array (); |
1116
|
1 |
|
$nameEmail = $this->getUsersNameAndEmail(); |
1117
|
1 |
|
$prefAddr = $nameEmail['email']; |
1118
|
1 |
|
$fullName = $nameEmail['name']; |
1119
|
1 |
|
if (empty ($prefAddr)) { |
1120
|
|
|
$nameEmail = $this->getSystemDefaultNameAndEmail(); |
1121
|
|
|
$prefAddr = $nameEmail['email']; |
1122
|
|
|
$fullName = $nameEmail['name']; |
1123
|
|
|
} // if |
1124
|
1 |
|
$fullName = from_html($fullName); |
1125
|
1 |
|
$ret['name'] = $fullName; |
1126
|
1 |
|
$ret['email'] = $prefAddr; |
1127
|
1 |
|
return $ret; |
1128
|
|
|
} |
1129
|
|
|
|
1130
|
1 |
|
function getUsersNameAndEmail() |
1131
|
|
|
{ |
1132
|
|
|
// Bug #48555 Not User Name Format of User's locale. |
1133
|
1 |
|
$this->_create_proper_name_field(); |
1134
|
|
|
|
1135
|
1 |
|
$prefAddr = $this->emailAddress->getPrimaryAddress($this); |
1136
|
|
|
|
1137
|
1 |
|
if (empty ($prefAddr)) { |
1138
|
|
|
$prefAddr = $this->emailAddress->getReplyToAddress($this); |
1139
|
|
|
} |
1140
|
1 |
|
return array('email' => $prefAddr , 'name' => $this->name); |
1141
|
|
|
|
1142
|
|
|
} // fn |
1143
|
|
|
|
1144
|
1 |
|
function getSystemDefaultNameAndEmail() { |
1145
|
|
|
|
1146
|
1 |
|
$email = new Email(); |
1147
|
1 |
|
$return = $email->getSystemDefaultEmail(); |
1148
|
1 |
|
$prefAddr = $return['email']; |
1149
|
1 |
|
$fullName = $return['name']; |
1150
|
1 |
|
return array('email' => $prefAddr , 'name' => $fullName); |
1151
|
|
|
} // fn |
1152
|
|
|
|
1153
|
|
|
/** |
1154
|
|
|
* sets User email default in config.php if not already set by install - i. |
1155
|
|
|
* e., upgrades |
1156
|
|
|
*/ |
1157
|
1 |
|
function setDefaultsInConfig() { |
1158
|
1 |
|
global $sugar_config; |
1159
|
1 |
|
$sugar_config['email_default_client'] = 'sugar'; |
1160
|
1 |
|
$sugar_config['email_default_editor'] = 'html'; |
1161
|
1 |
|
ksort($sugar_config); |
1162
|
1 |
|
write_array_to_file('sugar_config', $sugar_config, 'config.php'); |
1163
|
1 |
|
return $sugar_config; |
1164
|
|
|
} |
1165
|
|
|
|
1166
|
|
|
/** |
1167
|
|
|
* returns User's email address based on descending order of preferences |
1168
|
|
|
* |
1169
|
|
|
* @param string id GUID of target user if needed |
1170
|
|
|
* @return array Assoc array for an email and name |
1171
|
|
|
*/ |
1172
|
1 |
|
function getEmailInfo($id='') { |
1173
|
1 |
|
$user = $this; |
1174
|
1 |
|
if(!empty($id)) { |
1175
|
1 |
|
$user = new User(); |
1176
|
1 |
|
$user->retrieve($id); |
1177
|
|
|
} |
1178
|
|
|
|
1179
|
|
|
// from name |
1180
|
1 |
|
$fromName = $user->getPreference('mail_fromname'); |
1181
|
1 |
|
if(empty($fromName)) { |
1182
|
|
|
// cn: bug 8586 - localized name format |
1183
|
1 |
|
$fromName = $user->full_name; |
1184
|
|
|
} |
1185
|
|
|
|
1186
|
|
|
// from address |
1187
|
1 |
|
$fromaddr = $user->getPreference('mail_fromaddress'); |
1188
|
1 |
|
if(empty($fromaddr)) { |
1189
|
1 |
|
if(!empty($user->email1) && isset($user->email1)) { |
1190
|
1 |
|
$fromaddr = $user->email1; |
1191
|
|
|
} elseif(!empty($user->email2) && isset($user->email2)) { |
1192
|
|
|
$fromaddr = $user->email2; |
1193
|
|
|
} else { |
1194
|
|
|
$r = $user->db->query("SELECT value FROM config WHERE name = 'fromaddress'"); |
1195
|
|
|
$a = $user->db->fetchByAssoc($r); |
1196
|
|
|
$fromddr = $a['value']; |
1197
|
|
|
} |
1198
|
|
|
} |
1199
|
|
|
|
1200
|
1 |
|
$ret['name'] = $fromName; |
1201
|
1 |
|
$ret['email'] = $fromaddr; |
1202
|
|
|
|
1203
|
1 |
|
return $ret; |
1204
|
|
|
} |
1205
|
|
|
|
1206
|
|
|
/** |
1207
|
|
|
* returns opening <a href=xxxx for a contact, account, etc |
1208
|
|
|
* cascades from User set preference to System-wide default |
1209
|
|
|
* @return string link |
1210
|
|
|
* @param attribute the email addy |
1211
|
|
|
* @param focus the parent bean |
1212
|
|
|
* @param contact_id |
1213
|
|
|
* @param return_module |
1214
|
|
|
* @param return_action |
1215
|
|
|
* @param return_id |
1216
|
|
|
* @param class |
1217
|
|
|
*/ |
1218
|
1 |
|
function getEmailLink2($emailAddress, &$focus, $contact_id='', $ret_module='', $ret_action='DetailView', $ret_id='', $class='') { |
1219
|
1 |
|
$emailLink = ''; |
1220
|
1 |
|
global $sugar_config; |
1221
|
|
|
|
1222
|
1 |
|
if(!isset($sugar_config['email_default_client'])) { |
1223
|
|
|
$this->setDefaultsInConfig(); |
1224
|
|
|
} |
1225
|
|
|
|
1226
|
1 |
|
$userPref = $this->getPreference('email_link_type'); |
1227
|
1 |
|
$defaultPref = $sugar_config['email_default_client']; |
1228
|
1 |
|
if($userPref != '') { |
1229
|
1 |
|
$client = $userPref; |
1230
|
|
|
} else { |
1231
|
|
|
$client = $defaultPref; |
1232
|
|
|
} |
1233
|
|
|
|
1234
|
1 |
|
if($client == 'sugar') { |
1235
|
1 |
|
$email = ''; |
1236
|
1 |
|
$to_addrs_ids = ''; |
1237
|
1 |
|
$to_addrs_names = ''; |
1238
|
1 |
|
$to_addrs_emails = ''; |
1239
|
|
|
|
1240
|
1 |
|
$fullName = !empty($focus->name) ? $focus->name : ''; |
1241
|
|
|
|
1242
|
1 |
|
if(empty($ret_module)) $ret_module = $focus->module_dir; |
1243
|
1 |
|
if(empty($ret_id)) $ret_id = $focus->id; |
1244
|
1 |
|
if($focus->object_name == 'Contact') { |
1245
|
1 |
|
$contact_id = $focus->id; |
1246
|
1 |
|
$to_addrs_ids = $focus->id; |
1247
|
|
|
// Bug #48555 Not User Name Format of User's locale. |
1248
|
1 |
|
$focus->_create_proper_name_field(); |
1249
|
1 |
|
$fullName = $focus->name; |
1250
|
1 |
|
$to_addrs_names = $fullName; |
1251
|
1 |
|
$to_addrs_emails = $focus->email1; |
1252
|
|
|
} |
1253
|
|
|
|
1254
|
1 |
|
$emailLinkUrl = 'contact_id='.$contact_id. |
1255
|
1 |
|
'&parent_type='.$focus->module_dir. |
1256
|
1 |
|
'&parent_id='.$focus->id. |
1257
|
1 |
|
'&parent_name='.urlencode($fullName). |
1258
|
1 |
|
'&to_addrs_ids='.$to_addrs_ids. |
1259
|
1 |
|
'&to_addrs_names='.urlencode($to_addrs_names). |
1260
|
1 |
|
'&to_addrs_emails='.urlencode($to_addrs_emails). |
1261
|
1 |
|
'&to_email_addrs='.urlencode($fullName . ' <' . $emailAddress . '>'). |
1262
|
1 |
|
'&return_module='.$ret_module. |
1263
|
1 |
|
'&return_action='.$ret_action. |
1264
|
1 |
|
'&return_id='.$ret_id; |
1265
|
|
|
|
1266
|
|
|
//Generate the compose package for the quick create options. |
1267
|
|
|
//$json = getJSONobj(); |
1268
|
|
|
//$composeOptionsLink = $json->encode( array('composeOptionsLink' => $emailLinkUrl,'id' => $focus->id) ); |
1269
|
1 |
|
require_once('modules/Emails/EmailUI.php'); |
1270
|
1 |
|
$eUi = new EmailUI(); |
1271
|
1 |
|
$j_quickComposeOptions = $eUi->generateComposePackageForQuickCreateFromComposeUrl($emailLinkUrl, true); |
1272
|
|
|
|
1273
|
1 |
|
$emailLink = "<a href='javascript:void(0);' onclick='SUGAR.quickCompose.init($j_quickComposeOptions);' class='$class'>"; |
1274
|
|
|
|
1275
|
|
|
} else { |
1276
|
|
|
// straight mailto: |
1277
|
|
|
$emailLink = '<a href="mailto:'.$emailAddress.'" class="'.$class.'">'; |
1278
|
|
|
} |
1279
|
|
|
|
1280
|
1 |
|
return $emailLink; |
1281
|
|
|
} |
1282
|
|
|
|
1283
|
|
|
/** |
1284
|
|
|
* returns opening <a href=xxxx for a contact, account, etc |
1285
|
|
|
* cascades from User set preference to System-wide default |
1286
|
|
|
* @return string link |
1287
|
|
|
* @param attribute the email addy |
1288
|
|
|
* @param focus the parent bean |
1289
|
|
|
* @param contact_id |
1290
|
|
|
* @param return_module |
1291
|
|
|
* @param return_action |
1292
|
|
|
* @param return_id |
1293
|
|
|
* @param class |
1294
|
|
|
*/ |
1295
|
10 |
|
function getEmailLink($attribute, &$focus, $contact_id='', $ret_module='', $ret_action='DetailView', $ret_id='', $class='') { |
1296
|
10 |
|
$emailLink = ''; |
1297
|
10 |
|
global $sugar_config; |
1298
|
|
|
|
1299
|
10 |
|
if(!isset($sugar_config['email_default_client'])) { |
1300
|
|
|
$this->setDefaultsInConfig(); |
1301
|
|
|
} |
1302
|
|
|
|
1303
|
10 |
|
$userPref = $this->getPreference('email_link_type'); |
1304
|
10 |
|
$defaultPref = $sugar_config['email_default_client']; |
1305
|
10 |
|
if($userPref != '') { |
1306
|
10 |
|
$client = $userPref; |
1307
|
|
|
} else { |
1308
|
|
|
$client = $defaultPref; |
1309
|
|
|
} |
1310
|
|
|
|
1311
|
10 |
|
if($client == 'sugar') { |
1312
|
10 |
|
$email = ''; |
1313
|
10 |
|
$to_addrs_ids = ''; |
1314
|
10 |
|
$to_addrs_names = ''; |
1315
|
10 |
|
$to_addrs_emails = ''; |
1316
|
|
|
|
1317
|
10 |
|
$fullName = !empty($focus->name) ? $focus->name : ''; |
1318
|
|
|
|
1319
|
10 |
|
if(!empty($focus->$attribute)) { |
1320
|
1 |
|
$email = $focus->$attribute; |
1321
|
|
|
} |
1322
|
|
|
|
1323
|
|
|
|
1324
|
10 |
|
if(empty($ret_module)) $ret_module = $focus->module_dir; |
1325
|
10 |
|
if(empty($ret_id)) $ret_id = $focus->id; |
1326
|
10 |
|
if($focus->object_name == 'Contact') { |
1327
|
|
|
// Bug #48555 Not User Name Format of User's locale. |
1328
|
2 |
|
$focus->_create_proper_name_field(); |
1329
|
2 |
|
$fullName = $focus->name; |
1330
|
2 |
|
$contact_id = $focus->id; |
1331
|
2 |
|
$to_addrs_ids = $focus->id; |
1332
|
2 |
|
$to_addrs_names = $fullName; |
1333
|
2 |
|
$to_addrs_emails = $focus->email1; |
1334
|
|
|
} |
1335
|
|
|
|
1336
|
10 |
|
$emailLinkUrl = 'contact_id='.$contact_id. |
1337
|
10 |
|
'&parent_type='.$focus->module_dir. |
1338
|
10 |
|
'&parent_id='.$focus->id. |
1339
|
10 |
|
'&parent_name='.urlencode($fullName). |
1340
|
10 |
|
'&to_addrs_ids='.$to_addrs_ids. |
1341
|
10 |
|
'&to_addrs_names='.urlencode($to_addrs_names). |
1342
|
10 |
|
'&to_addrs_emails='.urlencode($to_addrs_emails). |
1343
|
10 |
|
'&to_email_addrs='.urlencode($fullName . ' <' . $email . '>'). |
1344
|
10 |
|
'&return_module='.$ret_module. |
1345
|
10 |
|
'&return_action='.$ret_action. |
1346
|
10 |
|
'&return_id='.$ret_id; |
1347
|
|
|
|
1348
|
|
|
//Generate the compose package for the quick create options. |
1349
|
10 |
|
require_once('modules/Emails/EmailUI.php'); |
1350
|
10 |
|
$eUi = new EmailUI(); |
1351
|
10 |
|
$j_quickComposeOptions = $eUi->generateComposePackageForQuickCreateFromComposeUrl($emailLinkUrl, true); |
1352
|
10 |
|
$emailLink = "<a href='javascript:void(0);' onclick='SUGAR.quickCompose.init($j_quickComposeOptions);' class='$class'>"; |
1353
|
|
|
|
1354
|
|
|
} else { |
1355
|
|
|
// straight mailto: |
1356
|
|
|
$emailLink = '<a href="mailto:'.$focus->$attribute.'" class="'.$class.'">'; |
1357
|
|
|
} |
1358
|
|
|
|
1359
|
10 |
|
return $emailLink; |
1360
|
|
|
} |
1361
|
|
|
|
1362
|
|
|
|
1363
|
|
|
/** |
1364
|
|
|
* gets a human-readable explanation of the format macro |
1365
|
|
|
* @return string Human readable name format |
1366
|
|
|
*/ |
1367
|
1 |
|
function getLocaleFormatDesc() { |
1368
|
1 |
|
global $locale; |
1369
|
1 |
|
global $mod_strings; |
1370
|
1 |
|
global $app_strings; |
1371
|
|
|
|
1372
|
1 |
|
$format['f'] = $mod_strings['LBL_LOCALE_DESC_FIRST']; |
1373
|
1 |
|
$format['l'] = $mod_strings['LBL_LOCALE_DESC_LAST']; |
1374
|
1 |
|
$format['s'] = $mod_strings['LBL_LOCALE_DESC_SALUTATION']; |
1375
|
1 |
|
$format['t'] = $mod_strings['LBL_LOCALE_DESC_TITLE']; |
1376
|
|
|
|
1377
|
1 |
|
$name['f'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_FIRST']; |
1378
|
1 |
|
$name['l'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_LAST']; |
1379
|
1 |
|
$name['s'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_SALUTATION']; |
1380
|
1 |
|
$name['t'] = $app_strings['LBL_LOCALE_NAME_EXAMPLE_TITLE']; |
1381
|
|
|
|
1382
|
1 |
|
$macro = $locale->getLocaleFormatMacro(); |
1383
|
|
|
|
1384
|
1 |
|
$ret1 = ''; |
1385
|
1 |
|
$ret2 = ''; |
1386
|
1 |
|
for($i=0; $i<strlen($macro); $i++) { |
1387
|
1 |
|
if(array_key_exists($macro{$i}, $format)) { |
1388
|
1 |
|
$ret1 .= "<i>".$format[$macro{$i}]."</i>"; |
1389
|
1 |
|
$ret2 .= "<i>".$name[$macro{$i}]."</i>"; |
1390
|
|
|
} else { |
1391
|
1 |
|
$ret1 .= $macro{$i}; |
1392
|
1 |
|
$ret2 .= $macro{$i}; |
1393
|
|
|
} |
1394
|
|
|
} |
1395
|
1 |
|
return $ret1."<br />".$ret2; |
1396
|
|
|
} |
1397
|
|
|
|
1398
|
|
|
|
1399
|
|
|
/* |
1400
|
|
|
* |
1401
|
|
|
* Here are the multi level admin access check functions. |
1402
|
|
|
* |
1403
|
|
|
*/ |
1404
|
|
|
/** |
1405
|
|
|
* Helper function to remap some modules around ACL wise |
1406
|
|
|
* |
1407
|
|
|
* @return string |
1408
|
|
|
*/ |
1409
|
5 |
|
protected function _fixupModuleForACL($module) { |
1410
|
5 |
|
if($module=='ContractTypes') { |
1411
|
|
|
$module = 'Contracts'; |
1412
|
|
|
} |
1413
|
5 |
|
if(preg_match('/Product[a-zA-Z]*/',$module)) { |
1414
|
5 |
|
$module = 'Products'; |
1415
|
|
|
} |
1416
|
|
|
|
1417
|
5 |
|
return $module; |
1418
|
|
|
} |
1419
|
|
|
/** |
1420
|
|
|
* Helper function that enumerates the list of modules and checks if they are an admin/dev. |
1421
|
|
|
* The code was just too similar to copy and paste. |
1422
|
|
|
* |
1423
|
|
|
* @return array |
1424
|
|
|
*/ |
1425
|
5 |
|
protected function _getModulesForACL($type='dev'){ |
1426
|
5 |
|
$isDev = $type=='dev'; |
1427
|
5 |
|
$isAdmin = $type=='admin'; |
1428
|
|
|
|
1429
|
5 |
|
global $beanList; |
1430
|
5 |
|
$myModules = array(); |
1431
|
|
|
|
1432
|
5 |
|
if (!is_array($beanList) ) { |
1433
|
|
|
return $myModules; |
1434
|
|
|
} |
1435
|
|
|
|
1436
|
|
|
// These modules don't take kindly to the studio trying to play about with them. |
1437
|
5 |
|
static $ignoredModuleList = array('iFrames','Feeds','Home','Dashboard','Calendar','Activities','Reports'); |
1438
|
|
|
|
1439
|
|
|
|
1440
|
5 |
|
$actions = ACLAction::getUserActions($this->id); |
1441
|
|
|
|
1442
|
5 |
|
foreach ($beanList as $module=>$val) { |
1443
|
|
|
// Remap the module name |
1444
|
5 |
|
$module = $this->_fixupModuleForACL($module); |
1445
|
5 |
|
if (in_array($module,$myModules)) { |
1446
|
|
|
// Already have the module in the list |
1447
|
|
|
continue; |
1448
|
|
|
} |
1449
|
5 |
|
if (in_array($module,$ignoredModuleList)) { |
1450
|
|
|
// You can't develop on these modules. |
1451
|
|
|
continue; |
1452
|
|
|
} |
1453
|
|
|
|
1454
|
5 |
|
$focus = SugarModule::get($module)->loadBean(); |
1455
|
5 |
|
if ( $focus instanceOf SugarBean ) { |
1456
|
5 |
|
$key = $focus->acltype; |
1457
|
|
|
} else { |
1458
|
5 |
|
$key = 'module'; |
1459
|
|
|
} |
1460
|
|
|
|
1461
|
5 |
|
if (($this->isAdmin() && isset($actions[$module][$key])) |
1462
|
|
|
) { |
1463
|
5 |
|
$myModules[] = $module; |
1464
|
|
|
} |
1465
|
|
|
} |
1466
|
|
|
|
1467
|
5 |
|
return $myModules; |
1468
|
|
|
} |
1469
|
|
|
/** |
1470
|
|
|
* Is this user a system wide admin |
1471
|
|
|
* |
1472
|
|
|
* @return bool |
1473
|
|
|
*/ |
1474
|
99 |
|
public function isAdmin() { |
1475
|
99 |
|
if(isset($this->is_admin) |
1476
|
99 |
|
&&($this->is_admin == '1' || $this->is_admin === 'on')){ |
1477
|
7 |
|
return true; |
1478
|
|
|
} |
1479
|
96 |
|
return false; |
1480
|
|
|
} |
1481
|
|
|
/** |
1482
|
|
|
* Is this user a developer for any module |
1483
|
|
|
* |
1484
|
|
|
* @return bool |
1485
|
|
|
*/ |
1486
|
3 |
|
public function isDeveloperForAnyModule() { |
1487
|
3 |
|
if(empty($this->id)) { |
1488
|
|
|
// empty user is no developer |
1489
|
3 |
|
return false; |
1490
|
|
|
} |
1491
|
1 |
|
if ($this->isAdmin()) { |
1492
|
1 |
|
return true; |
1493
|
|
|
} |
1494
|
1 |
|
return false; |
1495
|
|
|
} |
1496
|
|
|
/** |
1497
|
|
|
* List the modules a user has developer access to |
1498
|
|
|
* |
1499
|
|
|
* @return array |
1500
|
|
|
*/ |
1501
|
2 |
|
public function getDeveloperModules() { |
1502
|
2 |
|
static $developerModules; |
1503
|
2 |
|
if (!isset($_SESSION[$this->user_name.'_get_developer_modules_for_user']) ) { |
1504
|
2 |
|
$_SESSION[$this->user_name.'_get_developer_modules_for_user'] = $this->_getModulesForACL('dev'); |
1505
|
|
|
} |
1506
|
|
|
|
1507
|
2 |
|
return $_SESSION[$this->user_name.'_get_developer_modules_for_user']; |
1508
|
|
|
} |
1509
|
|
|
/** |
1510
|
|
|
* Is this user a developer for the specified module |
1511
|
|
|
* |
1512
|
|
|
* @return bool |
1513
|
|
|
*/ |
1514
|
1 |
|
public function isDeveloperForModule($module) { |
1515
|
1 |
|
if(empty($this->id)) { |
1516
|
|
|
// empty user is no developer |
1517
|
1 |
|
return false; |
1518
|
|
|
} |
1519
|
1 |
|
if ($this->isAdmin()) { |
1520
|
1 |
|
return true; |
1521
|
|
|
} |
1522
|
|
|
|
1523
|
1 |
|
$devModules = $this->getDeveloperModules(); |
1524
|
|
|
|
1525
|
1 |
|
$module = $this->_fixupModuleForACL($module); |
1526
|
|
|
|
1527
|
1 |
|
if (in_array($module,$devModules) ) { |
1528
|
|
|
return true; |
1529
|
|
|
} |
1530
|
|
|
|
1531
|
1 |
|
return false; |
1532
|
|
|
} |
1533
|
|
|
/** |
1534
|
|
|
* List the modules a user has admin access to |
1535
|
|
|
* |
1536
|
|
|
* @return array |
1537
|
|
|
*/ |
1538
|
3 |
|
public function getAdminModules() { |
1539
|
3 |
|
if (!isset($_SESSION[$this->user_name.'_get_admin_modules_for_user']) ) { |
1540
|
3 |
|
$_SESSION[$this->user_name.'_get_admin_modules_for_user'] = $this->_getModulesForACL('admin'); |
1541
|
|
|
} |
1542
|
|
|
|
1543
|
3 |
|
return $_SESSION[$this->user_name.'_get_admin_modules_for_user']; |
1544
|
|
|
} |
1545
|
|
|
/** |
1546
|
|
|
* Is this user an admin for the specified module |
1547
|
|
|
* |
1548
|
|
|
* @return bool |
1549
|
|
|
*/ |
1550
|
52 |
|
public function isAdminForModule($module) { |
1551
|
52 |
|
if(empty($this->id)) { |
1552
|
|
|
// empty user is no admin |
1553
|
51 |
|
return false; |
1554
|
|
|
} |
1555
|
2 |
|
if ($this->isAdmin()) { |
1556
|
1 |
|
return true; |
1557
|
|
|
} |
1558
|
|
|
|
1559
|
2 |
|
$adminModules = $this->getAdminModules(); |
1560
|
|
|
|
1561
|
2 |
|
$module = $this->_fixupModuleForACL($module); |
1562
|
|
|
|
1563
|
2 |
|
if (in_array($module,$adminModules) ) { |
1564
|
|
|
return true; |
1565
|
|
|
} |
1566
|
|
|
|
1567
|
2 |
|
return false; |
1568
|
|
|
} |
1569
|
|
|
/** |
1570
|
|
|
* Whether or not based on the user's locale if we should show the last name first. |
1571
|
|
|
* |
1572
|
|
|
* @return bool |
1573
|
|
|
*/ |
1574
|
1 |
|
public function showLastNameFirst(){ |
1575
|
1 |
|
global $locale; |
1576
|
1 |
|
$localeFormat = $locale->getLocaleFormatMacro($this); |
1577
|
1 |
|
if ( strpos($localeFormat,'l') > strpos($localeFormat,'f') ) { |
1578
|
1 |
|
return false; |
1579
|
|
|
}else { |
1580
|
|
|
return true; |
1581
|
|
|
} |
1582
|
|
|
} |
1583
|
|
|
|
1584
|
2 |
|
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) |
1585
|
|
|
{ //call parent method, specifying for array to be returned |
1586
|
2 |
|
$ret_array = parent::create_new_list_query($order_by, $where,$filter,$params, $show_deleted,$join_type, true,$parentbean, $singleSelect,$ifListForExport); |
1587
|
|
|
|
1588
|
|
|
//if this is being called from webservices, then run additional code |
1589
|
2 |
|
if(!empty($GLOBALS['soap_server_object'])){ |
1590
|
|
|
|
1591
|
|
|
//if this is a single select, then secondary queries are being run that may result in duplicate rows being returned through the |
1592
|
|
|
//left joins with meetings/tasks/call. We need to change the left joins to include a null check (bug 40250) |
1593
|
|
|
if($singleSelect) |
1594
|
|
|
{ |
1595
|
|
|
//retrieve the 'from' string and make lowercase for easier manipulation |
1596
|
|
|
$left_str = strtolower($ret_array['from']); |
1597
|
|
|
$lefts = explode('left join', $left_str); |
1598
|
|
|
$new_left_str = ''; |
1599
|
|
|
|
1600
|
|
|
//explode on the left joins and process each one |
1601
|
|
|
foreach($lefts as $ljVal){ |
1602
|
|
|
//grab the join alias |
1603
|
|
|
$onPos = strpos( $ljVal, ' on'); |
1604
|
|
|
if($onPos === false){ |
1605
|
|
|
$new_left_str .=' '.$ljVal.' '; |
1606
|
|
|
continue; |
1607
|
|
|
} |
1608
|
|
|
$spacePos = strrpos(substr($ljVal, 0, $onPos),' '); |
1609
|
|
|
$alias = substr($ljVal,$spacePos,$onPos-$spacePos); |
1610
|
|
|
|
1611
|
|
|
//add null check to end of the Join statement |
1612
|
|
|
// Bug #46390 to use id_c field instead of id field for custom tables |
1613
|
|
|
if(substr($alias, -5) != '_cstm') |
1614
|
|
|
{ |
1615
|
|
|
$ljVal =' LEFT JOIN '.$ljVal.' and '.$alias.'.id is null '; |
1616
|
|
|
} |
1617
|
|
|
else |
1618
|
|
|
{ |
1619
|
|
|
$ljVal =' LEFT JOIN '.$ljVal.' and '.$alias.'.id_c is null '; |
1620
|
|
|
} |
1621
|
|
|
|
1622
|
|
|
//add statement into new string |
1623
|
|
|
$new_left_str .= $ljVal; |
1624
|
|
|
} |
1625
|
|
|
//replace the old string with the new one |
1626
|
|
|
$ret_array['from'] = $new_left_str; |
1627
|
|
|
} |
1628
|
|
|
} |
1629
|
|
|
|
1630
|
|
|
//return array or query string |
1631
|
2 |
|
if($return_array) |
1632
|
|
|
{ |
1633
|
2 |
|
return $ret_array; |
1634
|
|
|
} |
1635
|
|
|
|
1636
|
|
|
return $ret_array['select'] . $ret_array['from'] . $ret_array['where']. $ret_array['order_by']; |
1637
|
|
|
|
1638
|
|
|
|
1639
|
|
|
|
1640
|
|
|
} |
1641
|
|
|
|
1642
|
|
|
/** |
1643
|
|
|
* Get user first day of week. |
1644
|
|
|
* |
1645
|
|
|
* @param [User] $user user object, current user if not specified |
|
|
|
|
1646
|
|
|
* @return int : 0 = Sunday, 1 = Monday, etc... |
1647
|
|
|
*/ |
1648
|
10 |
|
public function get_first_day_of_week() |
1649
|
|
|
{ |
1650
|
10 |
|
$fdow = $this->getPreference('fdow'); |
1651
|
10 |
|
if (empty($fdow)) |
1652
|
|
|
{ |
1653
|
10 |
|
$fdow = 0; |
1654
|
|
|
} |
1655
|
|
|
|
1656
|
10 |
|
return $fdow; |
1657
|
|
|
} |
1658
|
|
|
|
1659
|
|
|
/** |
1660
|
|
|
* Method for password generation |
1661
|
|
|
* |
1662
|
|
|
* @static |
1663
|
|
|
* @return string password |
1664
|
|
|
*/ |
1665
|
1 |
|
public static function generatePassword() |
1666
|
|
|
{ |
1667
|
1 |
|
$res = $GLOBALS['sugar_config']['passwordsetting']; |
1668
|
1 |
|
$charBKT = ''; |
1669
|
|
|
//chars to select from |
1670
|
1 |
|
$LOWERCASE = "abcdefghijklmnpqrstuvwxyz"; |
1671
|
1 |
|
$NUMBER = "0123456789"; |
1672
|
1 |
|
$UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
1673
|
1 |
|
$SPECIAL = '~!@#$%^&*()_+=-{}|'; |
1674
|
1 |
|
$condition = 0; |
1675
|
1 |
|
$charBKT .= $UPPERCASE . $LOWERCASE . $NUMBER; |
1676
|
1 |
|
$password = ""; |
1677
|
1 |
|
$length = '6'; |
1678
|
|
|
|
1679
|
|
|
// Create random characters for the ones that doesnt have requirements |
1680
|
1 |
|
for ($i=0; $i < $length - $condition; $i ++) // loop and create password |
1681
|
|
|
{ |
1682
|
1 |
|
$password = $password . substr ($charBKT, rand() % strlen($charBKT), 1); |
1683
|
|
|
} |
1684
|
|
|
|
1685
|
1 |
|
return $password; |
1686
|
|
|
} |
1687
|
|
|
|
1688
|
|
|
/** |
1689
|
|
|
* Send new password or link to user |
1690
|
|
|
* |
1691
|
|
|
* @param string $templateId Id of email template |
1692
|
|
|
* @param array $additionalData additional params: link, url, password |
1693
|
|
|
* @return array status: true|false, message: error message, if status = false and message = '' it means that send method has returned false |
1694
|
|
|
*/ |
1695
|
1 |
|
public function sendEmailForPassword($templateId, array $additionalData = array()) |
1696
|
|
|
{ |
1697
|
1 |
|
global $sugar_config, $current_user; |
1698
|
1 |
|
$mod_strings = return_module_language('', 'Users'); |
1699
|
|
|
$result = array( |
1700
|
1 |
|
'status' => false, |
1701
|
|
|
'message' => '' |
1702
|
|
|
); |
1703
|
|
|
|
1704
|
1 |
|
$emailTemp = new EmailTemplate(); |
1705
|
1 |
|
$emailTemp->disable_row_level_security = true; |
1706
|
1 |
|
if ($emailTemp->retrieve($templateId) == '') |
1707
|
|
|
{ |
1708
|
1 |
|
$result['message'] = $mod_strings['LBL_EMAIL_TEMPLATE_MISSING']; |
1709
|
1 |
|
return $result; |
1710
|
|
|
} |
1711
|
|
|
|
1712
|
|
|
//replace instance variables in email templates |
1713
|
|
|
$htmlBody = $emailTemp->body_html; |
1714
|
|
|
$body = $emailTemp->body; |
1715
|
|
|
if (isset($additionalData['link']) && $additionalData['link'] == true) |
1716
|
|
|
{ |
1717
|
|
|
$htmlBody = str_replace('$contact_user_link_guid', $additionalData['url'], $htmlBody); |
1718
|
|
|
$body = str_replace('$contact_user_link_guid', $additionalData['url'], $body); |
1719
|
|
|
} |
1720
|
|
|
else |
1721
|
|
|
{ |
1722
|
|
|
$htmlBody = str_replace('$contact_user_user_hash', $additionalData['password'], $htmlBody); |
1723
|
|
|
$body = str_replace('$contact_user_user_hash', $additionalData['password'], $body); |
1724
|
|
|
} |
1725
|
|
|
// Bug 36833 - Add replacing of special value $instance_url |
1726
|
|
|
$htmlBody = str_replace('$config_site_url', $sugar_config['site_url'], $htmlBody); |
1727
|
|
|
$body = str_replace('$config_site_url', $sugar_config['site_url'], $body); |
1728
|
|
|
|
1729
|
|
|
$htmlBody = str_replace('$contact_user_user_name', $this->user_name, $htmlBody); |
1730
|
|
|
$htmlBody = str_replace('$contact_user_pwd_last_changed', TimeDate::getInstance()->nowDb(), $htmlBody); |
1731
|
|
|
$body = str_replace('$contact_user_user_name', $this->user_name, $body); |
1732
|
|
|
$body = str_replace('$contact_user_pwd_last_changed', TimeDate::getInstance()->nowDb(), $body); |
1733
|
|
|
$emailTemp->body_html = $htmlBody; |
1734
|
|
|
$emailTemp->body = $body; |
1735
|
|
|
|
1736
|
|
|
$itemail = $this->emailAddress->getPrimaryAddress($this); |
1737
|
|
|
//retrieve IT Admin Email |
1738
|
|
|
//_ppd( $emailTemp->body_html); |
1739
|
|
|
//retrieve email defaults |
1740
|
|
|
$emailObj = new Email(); |
1741
|
|
|
$defaults = $emailObj->getSystemDefaultEmail(); |
1742
|
|
|
require_once('include/SugarPHPMailer.php'); |
1743
|
|
|
$mail = new SugarPHPMailer(); |
1744
|
|
|
$mail->setMailerForSystem(); |
1745
|
|
|
//$mail->IsHTML(true); |
1746
|
|
|
$mail->From = $defaults['email']; |
1747
|
|
|
$mail->FromName = $defaults['name']; |
1748
|
|
|
$mail->ClearAllRecipients(); |
1749
|
|
|
$mail->ClearReplyTos(); |
1750
|
|
|
$mail->Subject = from_html($emailTemp->subject); |
1751
|
|
|
if ($emailTemp->text_only != 1) |
1752
|
|
|
{ |
1753
|
|
|
$mail->IsHTML(true); |
1754
|
|
|
$mail->Body = from_html($emailTemp->body_html); |
1755
|
|
|
$mail->AltBody = from_html($emailTemp->body); |
1756
|
|
|
} |
1757
|
|
|
else |
1758
|
|
|
{ |
1759
|
|
|
$mail->Body_html = from_html($emailTemp->body_html); |
1760
|
|
|
$mail->Body = from_html($emailTemp->body); |
1761
|
|
|
} |
1762
|
|
|
if ($mail->Body == '' && $current_user->is_admin) |
1763
|
|
|
{ |
1764
|
|
|
global $app_strings; |
1765
|
|
|
$result['message'] = $app_strings['LBL_EMAIL_TEMPLATE_EDIT_PLAIN_TEXT']; |
1766
|
|
|
return $result; |
1767
|
|
|
} |
1768
|
|
|
if ($mail->Mailer == 'smtp' && $mail->Host =='' && $current_user->is_admin) |
1769
|
|
|
{ |
1770
|
|
|
$result['message'] = $mod_strings['ERR_SERVER_SMTP_EMPTY']; |
1771
|
|
|
return $result; |
1772
|
|
|
} |
1773
|
|
|
|
1774
|
|
|
$mail->prepForOutbound(); |
1775
|
|
|
$hasRecipients = false; |
1776
|
|
|
|
1777
|
|
|
if (!empty($itemail)) |
1778
|
|
|
{ |
1779
|
|
|
if ($hasRecipients) |
1780
|
|
|
{ |
1781
|
|
|
$mail->AddBCC($itemail); |
1782
|
|
|
} |
1783
|
|
|
else |
1784
|
|
|
{ |
1785
|
|
|
$mail->AddAddress($itemail); |
1786
|
|
|
} |
1787
|
|
|
$hasRecipients = true; |
1788
|
|
|
} |
1789
|
|
|
if ($hasRecipients) |
1790
|
|
|
{ |
1791
|
|
|
$result['status'] = @$mail->Send(); |
1792
|
|
|
} |
1793
|
|
|
|
1794
|
|
|
if ($result['status'] == true) |
1795
|
|
|
{ |
1796
|
|
|
$emailObj->team_id = 1; |
1797
|
|
|
$emailObj->to_addrs = ''; |
1798
|
|
|
$emailObj->type = 'archived'; |
1799
|
|
|
$emailObj->deleted = '0'; |
1800
|
|
|
$emailObj->name = $mail->Subject ; |
1801
|
|
|
$emailObj->description = $mail->Body; |
1802
|
|
|
$emailObj->description_html = null; |
1803
|
|
|
$emailObj->from_addr = $mail->From; |
1804
|
|
|
$emailObj->parent_type = 'User'; |
1805
|
|
|
$emailObj->date_sent = TimeDate::getInstance()->nowDb(); |
1806
|
|
|
$emailObj->modified_user_id = '1'; |
1807
|
|
|
$emailObj->created_by = '1'; |
1808
|
|
|
$emailObj->status = 'sent'; |
1809
|
|
|
$emailObj->save(); |
1810
|
|
|
if (!isset($additionalData['link']) || $additionalData['link'] == false) |
1811
|
|
|
{ |
1812
|
|
|
$this->setNewPassword($additionalData['password'], '1'); |
1813
|
|
|
} |
1814
|
|
|
} |
1815
|
|
|
|
1816
|
|
|
return $result; |
1817
|
|
|
} |
1818
|
|
|
|
1819
|
|
|
// Bug #48014 Must to send password to imported user if this action is required |
1820
|
1 |
|
function afterImportSave() |
1821
|
|
|
{ |
1822
|
|
|
if( |
1823
|
1 |
|
$this->user_hash == false |
1824
|
1 |
|
&& !$this->is_group |
1825
|
1 |
|
&& !$this->portal_only |
1826
|
1 |
|
&& isset($GLOBALS['sugar_config']['passwordsetting']['SystemGeneratedPasswordON']) |
1827
|
1 |
|
&& $GLOBALS['sugar_config']['passwordsetting']['SystemGeneratedPasswordON'] |
1828
|
|
|
) |
1829
|
|
|
{ |
1830
|
1 |
|
$backUpPost = $_POST; |
1831
|
|
|
$_POST = array( |
1832
|
1 |
|
'userId' => $this->id |
1833
|
|
|
); |
1834
|
1 |
|
ob_start(); |
1835
|
1 |
|
require('modules/Users/GeneratePassword.php'); |
1836
|
1 |
|
$result = ob_get_clean(); |
1837
|
1 |
|
$_POST = $backUpPost; |
1838
|
1 |
|
return $result == true; |
|
|
|
|
1839
|
|
|
} |
1840
|
|
|
} |
1841
|
|
|
|
1842
|
|
|
/** |
1843
|
|
|
* Checks if the passed email is primary. |
1844
|
|
|
* |
1845
|
|
|
* @param string $email |
1846
|
|
|
* @return bool Returns TRUE if the passed email is primary. |
1847
|
|
|
*/ |
1848
|
1 |
|
public function isPrimaryEmail($email) |
1849
|
|
|
{ |
1850
|
1 |
|
if (!empty($this->email1) && !empty($email) && strcasecmp($this->email1, $email) == 0) { |
1851
|
1 |
|
return true; |
1852
|
|
|
} else { |
1853
|
1 |
|
return false; |
1854
|
|
|
} |
1855
|
|
|
} |
1856
|
|
|
} |
1857
|
|
|
|
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
orexit
statements that have been added for debug purposes.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.