]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - service/core/SoapHelperWebService.php
Release 6.4.0
[Github/sugarcrm.git] / service / core / SoapHelperWebService.php
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-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 global $disable_date_format;
40 $disable_date_format = true;
41
42 class SoapHelperWebServices {
43
44         function get_field_list($value, $fields, $translate=true)
45         {
46                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_field_list('.print_r($value, true).', '.print_r($fields, true).", $translate");
47                 $module_fields = array();
48                 $link_fields = array();
49                 if(!empty($value->field_defs)){
50
51                         foreach($value->field_defs as $var){
52                                 if(!empty($fields) && !in_array( $var['name'], $fields))continue;
53                                 if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'non-db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate'))continue;
54                                 if ($var['source'] == 'non_db' && (isset($var['type']) && $var['type'] != 'link')) {
55                                         continue;
56                                 }
57                                 $required = 0;
58                                 $options_dom = array();
59                                 $options_ret = array();
60                                 // Apparently the only purpose of this check is to make sure we only return fields
61                                 //   when we've read a record.  Otherwise this function is identical to get_module_field_list
62
63                                 if( isset($var['required']) && $var['required'] && $var['required'] !== 'false' ){
64                                         $required = 1;
65                                 }
66                                 if(isset($var['options'])){
67                                         $options_dom = translate($var['options'], $value->module_dir);
68                                         if(!is_array($options_dom)) $options_dom = array();
69                                         foreach($options_dom as $key=>$oneOption)
70                                                 $options_ret[$key] = $this->get_name_value($key,$oneOption);
71                                 }
72
73                     if(!empty($var['dbType']) && $var['type'] == 'bool') {
74                         $options_ret['type'] = $this->get_name_value('type', $var['dbType']);
75                     }
76
77                     $entry = array();
78                     $entry['name'] = $var['name'];
79                     $entry['type'] = $var['type'];
80                     if ($var['type'] == 'link') {
81                             $entry['relationship'] = (isset($var['relationship']) ? $var['relationship'] : '');
82                             $entry['module'] = (isset($var['module']) ? $var['module'] : '');
83                             $entry['bean_name'] = (isset($var['bean_name']) ? $var['bean_name'] : '');
84                                         $link_fields[$var['name']] = $entry;
85                     } else {
86                             if($translate) {
87                                 $entry['label'] = isset($var['vname']) ? translate($var['vname'], $value->module_dir) : $var['name'];
88                             } else {
89                                 $entry['label'] = isset($var['vname']) ? $var['vname'] : $var['name'];
90                             }
91                             $entry['required'] = $required;
92                             $entry['options'] = $options_ret;
93                                         if(isset($var['default'])) {
94                                            $entry['default_value'] = $var['default'];
95                                         }
96                                         $module_fields[$var['name']] = $entry;
97                     } // else
98                         } //foreach
99                 } //if
100
101                 if($value->module_dir == 'Bugs'){
102                         require_once('modules/Releases/Release.php');
103                         $seedRelease = new Release();
104                         $options = $seedRelease->get_releases(TRUE, "Active");
105                         $options_ret = array();
106                         foreach($options as $name=>$value){
107                                 $options_ret[] =  array('name'=> $name , 'value'=>$value);
108                         }
109                         if(isset($module_fields['fixed_in_release'])){
110                                 $module_fields['fixed_in_release']['type'] = 'enum';
111                                 $module_fields['fixed_in_release']['options'] = $options_ret;
112                         }
113                         if(isset($module_fields['release'])){
114                                 $module_fields['release']['type'] = 'enum';
115                                 $module_fields['release']['options'] = $options_ret;
116                         }
117                         if(isset($module_fields['release_name'])){
118                                 $module_fields['release_name']['type'] = 'enum';
119                                 $module_fields['release_name']['options'] = $options_ret;
120                         }
121                 }
122
123                 if(isset($value->assigned_user_name) && isset($module_fields['assigned_user_id'])) {
124                         $module_fields['assigned_user_name'] = $module_fields['assigned_user_id'];
125                         $module_fields['assigned_user_name']['name'] = 'assigned_user_name';
126                 }
127                 if(isset($module_fields['modified_user_id'])) {
128                         $module_fields['modified_by_name'] = $module_fields['modified_user_id'];
129                         $module_fields['modified_by_name']['name'] = 'modified_by_name';
130                 }
131                 if(isset($module_fields['created_by'])) {
132                         $module_fields['created_by_name'] = $module_fields['created_by'];
133                         $module_fields['created_by_name']['name'] = 'created_by_name';
134                 }
135
136         $return = array('module_fields' => $module_fields, 'link_fields' => $link_fields);
137         $GLOBALS['log']->info('End: SoapHelperWebServices->get_field_list ->> '.print_r($return, true));
138                 return $return;
139         } // fn
140
141         function setFaultObject($errorObject) {
142                 if ($this->isLogLevelDebug()) {
143                         $GLOBALS['log']->debug('SoapHelperWebServices->setFaultObject - ' . var_export($errorObject, true));
144                 }
145                 global $service_object;
146                 $service_object->error($errorObject);
147         } // fn
148
149 /**
150  * Validate the user session based on user name and password hash.
151  *
152  * @param string $user_name -- The user name to create a session for
153  * @param string $password -- The MD5 sum of the user's password
154  * @return true -- If the session is created
155  * @return false -- If the session is not created
156  */
157 function validate_user($user_name, $password){
158         $GLOBALS['log']->info('Begin: SoapHelperWebServices->validate_user');
159         global $server, $current_user, $sugar_config, $system_config;
160         $user = new User();
161         $user->user_name = $user_name;
162         $system_config = new Administration();
163         $system_config->retrieveSettings('system');
164         $authController = new AuthenticationController((!empty($sugar_config['authenticationClass'])? $sugar_config['authenticationClass'] : 'SugarAuthenticate'));
165         // Check to see if the user name and password are consistent.
166         if($user->authenticate_user($password)){
167                 // we also need to set the current_user.
168                 $user->retrieve($user->id);
169                 $current_user = $user;
170
171                 $GLOBALS['log']->info('End: SoapHelperWebServices->validate_user - validation passed');
172                 return true;
173         }else if(function_exists('mcrypt_cbc')){
174                 $password = $this->decrypt_string($password);
175                 if($authController->login($user_name, $password) && isset($_SESSION['authenticated_user_id'])){
176                         $user->retrieve($_SESSION['authenticated_user_id']);
177                         $current_user = $user;
178                         $GLOBALS['log']->info('End: SoapHelperWebServices->validate_user - validation passed');
179                         return true;
180                 }
181         }else{
182                 $GLOBALS['log']->fatal("SECURITY: failed attempted login for $user_name using SOAP api");
183                 $server->setError("Invalid username and/or password");
184                 return false;
185         }
186
187 }
188
189         /**
190          * Validate the provided session information is correct and current.  Load the session.
191          *
192          * @param String $session_id -- The session ID that was returned by a call to login.
193          * @return true -- If the session is valid and loaded.
194          * @return false -- if the session is not valid.
195          */
196         function validate_authenticated($session_id){
197                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->validate_authenticated');
198                 if(!empty($session_id)){
199                         session_id($session_id);
200                         if(empty($_SESSION)) {
201                            session_start();
202                         }
203                         if(!empty($_SESSION['is_valid_session']) && $this->is_valid_ip_address('ip_address') && $_SESSION['type'] == 'user'){
204
205                                 global $current_user;
206                                 require_once('modules/Users/User.php');
207                                 $current_user = new User();
208                                 $current_user->retrieve($_SESSION['user_id']);
209                                 $this->login_success();
210                                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->validate_authenticated - passed');
211                                 $GLOBALS['log']->info('End: SoapHelperWebServices->validate_authenticated');
212                                 return true;
213                         }
214
215                         $GLOBALS['log']->debug("calling destroy");
216                         session_destroy();
217                 }
218                 LogicHook::initialize();
219                 $GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
220                 $GLOBALS['log']->info('End: SoapHelperWebServices->validate_authenticated - validation failed');
221                 return false;
222         }
223
224         /**
225          * Use the same logic as in SugarAuthenticate to validate the ip address
226          *
227          * @param string $session_var
228          * @return bool - true if the ip address is valid, false otherwise.
229          */
230         function is_valid_ip_address($session_var){
231                 global $sugar_config;
232                 // grab client ip address
233                 $clientIP = query_client_ip();
234                 $classCheck = 0;
235                 // check to see if config entry is present, if not, verify client ip
236                 if (!isset ($sugar_config['verify_client_ip']) || $sugar_config['verify_client_ip'] == true) {
237                         // check to see if we've got a current ip address in $_SESSION
238                         // and check to see if the session has been hijacked by a foreign ip
239                         if (isset ($_SESSION[$session_var])) {
240                                 $session_parts = explode(".", $_SESSION[$session_var]);
241                                 $client_parts = explode(".", $clientIP);
242                     if(count($session_parts) < 4) {
243                         $classCheck = 0;
244                     }else {
245                                 // match class C IP addresses
246                                 for ($i = 0; $i < 3; $i ++) {
247                                         if ($session_parts[$i] == $client_parts[$i]) {
248                                                 $classCheck = 1;
249                                                         continue;
250                                         } else {
251                                                 $classCheck = 0;
252                                                 break;
253                                                 }
254                                         }
255                         }
256                                         // we have a different IP address
257                                         if ($_SESSION[$session_var] != $clientIP && empty ($classCheck)) {
258                                                 $GLOBALS['log']->fatal("IP Address mismatch: SESSION IP: {$_SESSION[$session_var]} CLIENT IP: {$clientIP}");
259                                                 return false;
260                                         }
261                                 } else {
262                                         return false;
263                                 }
264                 }
265                 return true;
266         }
267
268         function checkSessionAndModuleAccess($session, $login_error_key, $module_name, $access_level, $module_access_level_error_key, $errorObject) {
269                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->checkSessionAndModuleAccess - ' . $module_name);
270                 if(!$this->validate_authenticated($session)){
271                         $GLOBALS['log']->error('SoapHelperWebServices->checkSessionAndModuleAccess - validate_authenticated failed - ' . $module_name);
272                         $errorObject->set_error('invalid_session');
273                         $this->setFaultObject($errorObject);
274                         $GLOBALS['log']->info('End: SoapHelperWebServices->checkSessionAndModuleAccess -' . $module_name);
275                         return false;
276                 } // if
277
278                 global  $beanList, $beanFiles;
279                 if (!empty($module_name)) {
280                         if(empty($beanList[$module_name])){
281                                 $GLOBALS['log']->error('SoapHelperWebServices->checkSessionAndModuleAccess - module does not exists - ' . $module_name);
282                                 $errorObject->set_error('no_module');
283                                 $this->setFaultObject($errorObject);
284                                 $GLOBALS['log']->info('End: SoapHelperWebServices->checkSessionAndModuleAccess -' . $module_name);
285                                 return false;
286                         } // if
287                         global $current_user;
288                         if(!$this->check_modules_access($current_user, $module_name, $access_level)){
289                                 $GLOBALS['log']->error('SoapHelperWebServices->checkSessionAndModuleAccess - no module access - ' . $module_name);
290                                 $errorObject->set_error('no_access');
291                                 $this->setFaultObject($errorObject);
292                                 $GLOBALS['log']->info('End: SoapHelperWebServices->checkSessionAndModuleAccess - ' . $module_name);
293                                 return false;
294                         }
295                 } // if
296                 $GLOBALS['log']->info('End: SoapHelperWebServices->checkSessionAndModuleAccess - ' . $module_name);
297                 return true;
298         } // fn
299
300         function checkACLAccess($bean, $viewType, $errorObject, $error_key) {
301                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->checkACLAccess');
302                 if(!$bean->ACLAccess($viewType)) {
303                         $GLOBALS['log']->error('SoapHelperWebServices->checkACLAccess - no ACLAccess');
304                         $errorObject->set_error($error_key);
305                         $this->setFaultObject($errorObject);
306                         $GLOBALS['log']->info('End: SoapHelperWebServices->checkACLAccess');
307                         return false;
308                 } // if
309                 $GLOBALS['log']->info('End: SoapHelperWebServices->checkACLAccess');
310                 return true;
311         } // fn
312
313         function checkQuery($errorObject, $query, $order_by = '')
314     {
315         require_once 'include/SugarSQLValidate.php';
316         $valid = new SugarSQLValidate();
317         if(!$valid->validateQueryClauses($query, $order_by)) {
318                 $GLOBALS['log']->error("SoapHelperWebServices->checkQuery - bad query: $query $order_by");
319             $errorObject->set_error('no_access');
320                 $this->setFaultObject($errorObject);
321                 return false;
322         }
323         return true;
324     }
325
326         function get_name_value($field,$value){
327                 return array('name'=>$field, 'value'=>$value);
328         }
329
330         function get_user_module_list($user){
331                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_user_module_list');
332                 global $app_list_strings, $current_language;
333                 $app_list_strings = return_app_list_strings_language($current_language);
334                 $modules = query_module_access_list($user);
335                 ACLController :: filterModuleList($modules, false);
336                 global $modInvisList;
337
338                 foreach($modInvisList as $invis){
339                         $modules[$invis] = 'read_only';
340                 }
341
342                 $actions = ACLAction::getUserActions($user->id,true);
343                 foreach($actions as $key=>$value){
344                         if(isset($value['module']) && $value['module']['access']['aclaccess'] < ACL_ALLOW_ENABLED){
345                                 if ($value['module']['access']['aclaccess'] == ACL_ALLOW_DISABLED) {
346                                         unset($modules[$key]);
347                                 } else {
348                                         $modules[$key] = 'read_only';
349                                 } // else
350                         } else {
351                                 $modules[$key] = '';
352                         } // else
353                 } // foreach
354                 $GLOBALS['log']->info('End: SoapHelperWebServices->get_user_module_list');
355                 return $modules;
356
357         }
358
359         function check_modules_access($user, $module_name, $action='write'){
360                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->check_modules_access');
361                 if(!isset($_SESSION['avail_modules'])){
362                         $_SESSION['avail_modules'] = $this->get_user_module_list($user);
363                 }
364                 if(isset($_SESSION['avail_modules'][$module_name])){
365                         if($action == 'write' && $_SESSION['avail_modules'][$module_name] == 'read_only'){
366                                 if(is_admin($user)) {
367                                         $GLOBALS['log']->info('End: SoapHelperWebServices->check_modules_access - SUCCESS: Admin can even write to read_only module');
368                                         return true;
369                                 } // if
370                                 $GLOBALS['log']->info('End: SoapHelperWebServices->check_modules_access - FAILED: write action on read_only module only available to admins');
371                                 return false;
372                         }elseif($action == 'write' && strcmp(strtolower($module_name), 'users') == 0 && !$user->isAdminForModule($module_name)){
373                  //rrs bug: 46000 - If the client is trying to write to the Users module and is not an admin then we need to stop them
374                 return false;
375             }
376                         $GLOBALS['log']->info('End: SoapHelperWebServices->check_modules_access - SUCCESS');
377                         return true;
378                 }
379                 $GLOBALS['log']->info('End: SoapHelperWebServices->check_modules_access - FAILED: Module info not available in $_SESSION');
380                 return false;
381
382     }
383
384
385         function get_name_value_list($value){
386                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_name_value_list');
387                 global $app_list_strings;
388                 $list = array();
389                 if(!empty($value->field_defs)){
390                         if(isset($value->assigned_user_name)) {
391                                 $list['assigned_user_name'] = $this->get_name_value('assigned_user_name', $value->assigned_user_name);
392                         }
393                         if(isset($value->modified_by_name)) {
394                                 $list['modified_by_name'] = $this->get_name_value('modified_by_name', $value->modified_by_name);
395                         }
396                         if(isset($value->created_by_name)) {
397                                 $list['created_by_name'] = $this->get_name_value('created_by_name', $value->created_by_name);
398                         }
399                         foreach($value->field_defs as $var){
400                                 if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate'))continue;
401
402                                 if(isset($value->$var['name'])){
403                                         $val = $value->$var['name'];
404                                         $type = $var['type'];
405
406                                         if(strcmp($type, 'date') == 0){
407                                                 $val = substr($val, 0, 10);
408                                         }elseif(strcmp($type, 'enum') == 0 && !empty($var['options'])){
409                                                 //$val = $app_list_strings[$var['options']][$val];
410                                         }
411
412                                         $list[$var['name']] = $this->get_name_value($var['name'], $val);
413                                 }
414                         }
415                 }
416                 $GLOBALS['log']->info('End: SoapHelperWebServices->get_name_value_list');
417                 return $list;
418
419         }
420
421         function filter_fields($value, $fields) {
422                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->filter_fields');
423                 global $invalid_contact_fields;
424                 $filterFields = array();
425                 foreach($fields as $field){
426                         if (is_array($invalid_contact_fields)) {
427                                 if (in_array($field, $invalid_contact_fields)) {
428                                         continue;
429                                 } // if
430                         } // if
431                         if (isset($value->field_defs[$field])) {
432                                 $var = $value->field_defs[$field];
433                                 if(isset($var['source']) && ($var['source'] != 'db' && $var['source'] != 'custom_fields') && $var['name'] != 'email1' && $var['name'] != 'email2' && (!isset($var['type'])|| $var['type'] != 'relate')) {
434
435                                         if($value->module_dir == 'Emails' && (($var['name'] == 'description') || ($var['name'] == 'description_html') || ($var['name'] == 'from_addr_name') || ($var['name'] == 'reply_to_addr') || ($var['name'] == 'to_addrs_names') || ($var['name'] == 'cc_addrs_names') || ($var['name'] == 'bcc_addrs_names') || ($var['name'] == 'raw_source'))) {
436
437                                         } else {
438                                                 continue;
439                                         }
440                                 }
441                         } // if
442                         $filterFields[] = $field;
443                 } // foreach
444                 $GLOBALS['log']->info('End: SoapHelperWebServices->filter_fields');
445                 return $filterFields;
446         } // fn
447
448         function get_name_value_list_for_fields($value, $fields) {
449                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_name_value_list_for_fields');
450                 global $app_list_strings;
451                 global $invalid_contact_fields;
452
453                 $list = array();
454                 if(!empty($value->field_defs)){
455                         if(empty($fields))$fields = array_keys($value->field_defs);
456                         if(isset($value->assigned_user_name) && in_array('assigned_user_name', $fields)) {
457                                 $list['assigned_user_name'] = $this->get_name_value('assigned_user_name', $value->assigned_user_name);
458                         }
459                         if(isset($value->modified_by_name) && in_array('modified_by_name', $fields)) {
460                                 $list['modified_by_name'] = $this->get_name_value('modified_by_name', $value->modified_by_name);
461                         }
462                         if(isset($value->created_by_name) && in_array('created_by_name', $fields)) {
463                                 $list['created_by_name'] = $this->get_name_value('created_by_name', $value->created_by_name);
464                         }
465
466                         $filterFields = $this->filter_fields($value, $fields);
467                         foreach($filterFields as $field){
468                                 $var = $value->field_defs[$field];
469                                 if(isset($value->$var['name'])){
470                                         $val = $value->$var['name'];
471                                         $type = $var['type'];
472
473                                         if(strcmp($type, 'date') == 0){
474                                                 $val = substr($val, 0, 10);
475                                         }elseif(strcmp($type, 'enum') == 0 && !empty($var['options'])){
476                                                 //$val = $app_list_strings[$var['options']][$val];
477                                         }
478
479                                         $list[$var['name']] = $this->get_name_value($var['name'], $val);
480                                 } // if
481                         } // foreach
482                 } // if
483                 $GLOBALS['log']->info('End: SoapHelperWebServices->get_name_value_list_for_fields');
484                 if ($this->isLogLevelDebug()) {
485                         $GLOBALS['log']->debug('SoapHelperWebServices->get_name_value_list_for_fields - return data = ' . var_export($list, true));
486                 } // if
487                 return $list;
488
489         } // fn
490
491         function array_get_name_value_list($array){
492                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->array_get_name_value_list');
493                 $list = array();
494                 foreach($array as $name=>$value){
495                         $list[$name] = $this->get_name_value($name, $value);
496                 }
497                 $GLOBALS['log']->info('End: SoapHelperWebServices->array_get_name_value_list');
498                 return $list;
499
500         }
501
502         function array_get_name_value_lists($array){
503                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->array_get_name_value_lists');
504             $list = array();
505             foreach($array as $name=>$value){
506                 $tmp_value=$value;
507                 if(is_array($value)){
508                     $tmp_value = array();
509                     foreach($value as $k=>$v){
510                         $tmp_value[$k] = $this->get_name_value($k, $v);
511                     }
512                 }
513                 $list[$name] = $this->get_name_value($name, $tmp_value);
514             }
515                 $GLOBALS['log']->info('End: SoapHelperWebServices->array_get_name_value_lists');
516             return $list;
517         }
518
519         function name_value_lists_get_array($list){
520                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->name_value_lists_get_array');
521             $array = array();
522             foreach($list as $key=>$value){
523                 if(isset($value['value']) && isset($value['name'])){
524                     if(is_array($value['value'])){
525                         $array[$value['name']]=array();
526                         foreach($value['value'] as $v){
527                             $array[$value['name']][$v['name']]=$v['value'];
528                         }
529                     }else{
530                         $array[$value['name']]=$value['value'];
531                     }
532                 }
533             }
534                 $GLOBALS['log']->info('End: SoapHelperWebServices->name_value_lists_get_array');
535             return $array;
536         }
537
538         function array_get_return_value($array, $module){
539
540                 $GLOBALS['log']->info('Begin/End: SoapHelperWebServices->array_get_return_value');
541                 return Array('id'=>$array['id'],
542                                         'module_name'=> $module,
543                                         'name_value_list'=>$this->array_get_name_value_list($array)
544                                         );
545         }
546
547         function get_return_value_for_fields($value, $module, $fields) {
548                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_return_value_for_fields');
549                 global $module_name, $current_user;
550                 $module_name = $module;
551                 if($module == 'Users' && $value->id != $current_user->id){
552                         $value->user_hash = '';
553                 }
554                 $GLOBALS['log']->info('End: SoapHelperWebServices->get_return_value_for_fields');
555                 return Array('id'=>$value->id,
556                                         'module_name'=> $module,
557                                         'name_value_list'=>$this->get_name_value_list_for_fields($value, $fields)
558                                         );
559         }
560
561 /**
562  * Fetch and array of related records
563  *
564  * @param String $bean -- Primary record
565  * @param String $link_field_name -- The name of the relationship
566  * @param Array $link_module_fields -- The keys of the array are the SugarBean attributes, the values of the array are the values the attributes should have.
567  * @param String $optional_where -- IGNORED
568  * @return Array 'rows/fields_set_on_rows' -- The list of records and what fields were actually set for thos erecords
569 */
570
571         function getRelationshipResults($bean, $link_field_name, $link_module_fields, $optional_where = '') {
572                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->getRelationshipResults');
573                 require_once('include/TimeDate.php');
574                 global $current_user, $disable_date_format,  $timedate;
575
576                 $bean->load_relationship($link_field_name);
577                 if (isset($bean->$link_field_name)) {
578                         //First get all the related beans
579             $related_beans = $bean->$link_field_name->getBeans();
580                         $filterFields = $this->filter_fields($submodule, $link_module_fields);
581             //Create a list of field/value rows based on $link_module_fields
582                         $list = array();
583             foreach($related_beans as $id => $bean)
584             {
585                 $row = array();
586                 foreach ($filterFields as $field) {
587                     if (isset($bean->$field))
588                     {
589                         if (isset($bean->field_defs[$field]['type']) && $bean->field_defs[$field]['type'] == 'date') {
590                             $row[$field] = $timedate->to_display_date_time($bean->$field);
591                         }
592                         $row[$field] = $bean->$field;
593                     }
594                     else
595                     {
596                         $row[$field] = "";
597                     }
598                 }
599                 //Users can't see other user's hashes
600                 if(is_a($bean, 'User') && $current_user->id != $bean->id && isset($row['user_hash'])) {
601                     $row['user_hash'] = "";
602                 }
603                 $list[] = $row;
604             }
605                         $GLOBALS['log']->info('End: SoapHelperWebServices->getRelationshipResults');
606                         return array('rows' => $list, 'fields_set_on_rows' => $filterFields);
607                 } else {
608                         $GLOBALS['log']->info('End: SoapHelperWebServices->getRelationshipResults - ' . $link_field_name . ' relationship does not exists');
609                         return false;
610                 } // else
611
612         } // fn
613
614         function get_return_value_for_link_fields($bean, $module, $link_name_to_value_fields_array) {
615                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_return_value_for_link_fields');
616                 global $module_name, $current_user;
617                 $module_name = $module;
618                 if($module == 'Users' && $bean->id != $current_user->id){
619                         $bean->user_hash = '';
620                 }
621
622                 if (empty($link_name_to_value_fields_array) || !is_array($link_name_to_value_fields_array)) {
623                         $GLOBALS['log']->debug('End: SoapHelperWebServices->get_return_value_for_link_fields - Invalid link information passed ');
624                         return array();
625                 }
626
627                 if ($this->isLogLevelDebug()) {
628                         $GLOBALS['log']->debug('SoapHelperWebServices->get_return_value_for_link_fields - link info = ' . var_export($link_name_to_value_fields_array, true));
629                 } // if
630                 $link_output = array();
631                 foreach($link_name_to_value_fields_array as $link_name_value_fields) {
632                         if (!is_array($link_name_value_fields) || !isset($link_name_value_fields['name']) || !isset($link_name_value_fields['value'])) {
633                                 continue;
634                         }
635                         $link_field_name = $link_name_value_fields['name'];
636                         $link_module_fields = $link_name_value_fields['value'];
637                         if (is_array($link_module_fields) && !empty($link_module_fields)) {
638                                 $result = $this->getRelationshipResults($bean, $link_field_name, $link_module_fields);
639                                 if (!$result) {
640                                         $link_output[] = array('name' => $link_field_name, 'records' => array());
641                                         continue;
642                                 }
643                                 $list = $result['rows'];
644                                 $filterFields = $result['fields_set_on_rows'];
645                                 if ($list) {
646                                         $rowArray = array();
647                                         foreach($list as $row) {
648                                                 $nameValueArray = array();
649                                                 foreach ($filterFields as $field) {
650                                                         $nameValue = array();
651                                                         if (isset($row[$field])) {
652                                                                 $nameValueArray[$field] = $this->get_name_value($field, $row[$field]);
653                                                         } // if
654                                                 } // foreach
655                                                 $rowArray[] = $nameValueArray;
656                                         } // foreach
657                                         $link_output[] = array('name' => $link_field_name, 'records' => $rowArray);
658                                 } // if
659                         } // if
660                 } // foreach
661                 $GLOBALS['log']->debug('End: SoapHelperWebServices->get_return_value_for_link_fields');
662                 if ($this->isLogLevelDebug()) {
663                         $GLOBALS['log']->debug('SoapHelperWebServices->get_return_value_for_link_fields - output = ' . var_export($link_output, true));
664                 } // if
665                 return $link_output;
666         } // fn
667
668         /**
669          *
670          * @param String $module_name -- The name of the module that the primary record is from.  This name should be the name the module was developed under (changing a tab name is studio does not affect the name that should be passed into this method).
671          * @param String $module_id -- The ID of the bean in the specified module
672          * @param String $link_field_name - The relationship name for which to create realtionships.
673          * @param Array $related_ids -- The array of ids for which we want to create relationships
674          * @param Array $name_value_list -- The array of name value pair of additional attributes to be set when adding this relationship
675          * @param int delete -- If 0 then add relationship else delete this relationship data
676          * @return true on success, false on failure
677          */
678         function new_handle_set_relationship($module_name, $module_id, $link_field_name, $related_ids, $name_value_list, $delete) {
679                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->new_handle_set_relationship');
680             global  $beanList, $beanFiles;
681
682             if(empty($beanList[$module_name])) {
683                         $GLOBALS['log']->debug('SoapHelperWebServices->new_handle_set_relationship - module ' . $module_name . ' does not exists' );
684                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_relationship');
685                 return false;
686             } // if
687             $class_name = $beanList[$module_name];
688             require_once($beanFiles[$class_name]);
689             $mod = new $class_name();
690             $mod->retrieve($module_id);
691                 if(!$mod->ACLAccess('DetailView')){
692                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_relationship');
693                         return false;
694                 }
695
696                 if ($mod->load_relationship($link_field_name)) {
697                         if (!$delete) {
698                                 $name_value_pair = array();
699                                 if (!empty($name_value_list)) {
700                                         $relFields = $mod->$link_field_name->getRelatedFields();
701                                         if(!empty($relFields)){
702                                                 $relFieldsKeys = array_keys($relFields);
703                                                 foreach($name_value_list as $key => $value) {
704                                                         if (in_array($value['name'], $relFieldsKeys)) {
705                                                                 $name_value_pair[$value['name']] = $value['value'];
706                                                         } // if
707                                                 } // foreach
708                                         } // if
709                                 }
710                                 $mod->$link_field_name->add($related_ids, $name_value_pair);
711                         } else {
712                                 foreach($related_ids as $id) {
713                                         $mod->$link_field_name->delete($module_id, $id);
714                                 } // foreach
715                         } // else
716                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_relationship');
717                         return true;
718                 } else {
719                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_relationship');
720                         return false;
721                 }
722         }
723
724         function new_handle_set_entries($module_name, $name_value_lists, $select_fields = FALSE) {
725                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->new_handle_set_entries');
726                 global $beanList, $beanFiles, $current_user, $app_list_strings;
727
728                 $ret_values = array();
729
730                 $class_name = $beanList[$module_name];
731                 require_once($beanFiles[$class_name]);
732                 $ids = array();
733                 $count = 1;
734                 $total = sizeof($name_value_lists);
735                 foreach($name_value_lists as $name_value_list){
736                         $seed = new $class_name();
737
738                         $seed->update_vcal = false;
739                         foreach($name_value_list as $value){
740                                 if($value['name'] == 'id'){
741                                         $seed->retrieve($value['value']);
742                                         break;
743                                 }
744                         }
745
746                         foreach($name_value_list as $value) {
747                                 $val = $value['value'];
748                                 if($seed->field_name_map[$value['name']]['type'] == 'enum'){
749                                         $vardef = $seed->field_name_map[$value['name']];
750                                         if(isset($app_list_strings[$vardef['options']]) && !isset($app_list_strings[$vardef['options']][$value]) ) {
751                                                 if ( in_array($val,$app_list_strings[$vardef['options']]) ){
752                                                         $val = array_search($val,$app_list_strings[$vardef['options']]);
753                                                 }
754                                         }
755                                 }
756                                 if($module_name == 'Users' && !empty($seed->id) && ($seed->id != $current_user->id) && $value['name'] == 'user_hash'){
757                                         continue;
758                                 }
759
760                                 $seed->$value['name'] = $val;
761                         }
762
763                         if($count == $total){
764                                 $seed->update_vcal = false;
765                         }
766                         $count++;
767
768                         //Add the account to a contact
769                         if($module_name == 'Contacts'){
770                                 $GLOBALS['log']->debug('Creating Contact Account');
771                                 $this->add_create_account($seed);
772                                 $duplicate_id = $this->check_for_duplicate_contacts($seed);
773                                 if($duplicate_id == null){
774                                         if($seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
775                                                 $seed->save();
776                                                 if($seed->deleted == 1){
777                                                         $seed->mark_deleted($seed->id);
778                                                 }
779                                                 $ids[] = $seed->id;
780                                         }
781                                 }
782                                 else{
783                                         //since we found a duplicate we should set the sync flag
784                                         if( $seed->ACLAccess('Save')){
785                                                 $seed = new $class_name();
786                                                 $seed->id = $duplicate_id;
787                                                 $seed->contacts_users_id = $current_user->id;
788                                                 $seed->save();
789                                                 $ids[] = $duplicate_id;//we have a conflict
790                                         }
791                                 }
792                         }
793                         else if($module_name == 'Meetings' || $module_name == 'Calls'){
794                                 //we are going to check if we have a meeting in the system
795                                 //with the same outlook_id. If we do find one then we will grab that
796                                 //id and save it
797                                 if( $seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
798                                         if(empty($seed->id) && !isset($seed->id)){
799                                                 if(!empty($seed->outlook_id) && isset($seed->outlook_id)){
800                                                         //at this point we have an object that does not have
801                                                         //the id set, but does have the outlook_id set
802                                                         //so we need to query the db to find if we already
803                                                         //have an object with this outlook_id, if we do
804                                                         //then we can set the id, otherwise this is a new object
805                                                         $order_by = "";
806                                                         $query = $seed->table_name.".outlook_id = '".$GLOBALS['db']->quote($seed->outlook_id)."'";
807                                                         $response = $seed->get_list($order_by, $query, 0,-1,-1,0);
808                                                         $list = $response['list'];
809                                                         if(count($list) > 0){
810                                                                 foreach($list as $value)
811                                                                 {
812                                                                         $seed->id = $value->id;
813                                                                         break;
814                                                                 }
815                                                         }//fi
816                                                 }//fi
817                                         }//fi
818                                     if (empty($seed->reminder_time)) {
819                         $seed->reminder_time = -1;
820                     }
821                     if($seed->reminder_time == -1){
822                         $defaultRemindrTime = $current_user->getPreference('reminder_time');
823                         if ($defaultRemindrTime != -1){
824                             $seed->reminder_checked = '1';
825                             $seed->reminder_time = $defaultRemindrTime;
826                         }
827                     }
828                                         $seed->save();
829                                         $ids[] = $seed->id;
830                                 }//fi
831                         }
832                         else
833                         {
834                                 if( $seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
835                                         $seed->save();
836                                         $ids[] = $seed->id;
837                                 }
838                         }
839
840                         // if somebody is calling set_entries_detail() and wants fields returned...
841                         if ($select_fields !== FALSE) {
842                                 $ret_values[$count] = array();
843
844                                 foreach ($select_fields as $select_field) {
845                                         if (isset($seed->$select_field)) {
846                                                 $ret_values[$count][$select_field] = $this->get_name_value($select_field, $seed->$select_field);
847                                         }
848                                 }
849                         }
850                 }
851
852                 // handle returns for set_entries_detail() and set_entries()
853                 if ($select_fields !== FALSE) {
854                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_entries');
855                         return array(
856                                 'name_value_lists' => $ret_values,
857                         );
858                 }
859                 else {
860                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_entries');
861                         return array(
862                                 'ids' => $ids,
863                         );
864                 }
865         }
866
867         function get_return_value($value, $module){
868                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_return_value');
869                 global $module_name, $current_user;
870                 $module_name = $module;
871                 if($module == 'Users' && $value->id != $current_user->id){
872                         $value->user_hash = '';
873                 }
874                 $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_entries');
875                 return Array('id'=>$value->id,
876                                         'module_name'=> $module,
877                                         'name_value_list'=>$this->get_name_value_list($value)
878                                         );
879         }
880
881
882         function get_return_module_fields($value, $module,$fields, $translate=true){
883                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_return_module_fields');
884                 global $module_name;
885                 $module_name = $module;
886                 $result = $this->get_field_list($value,$fields,  $translate);
887                 $GLOBALS['log']->info('End: SoapHelperWebServices->get_return_module_fields');
888                 return Array('module_name'=>$module,
889                                         'module_fields'=> $result['module_fields'],
890                                         'link_fields'=> $result['link_fields'],
891                                         );
892         } // fn
893
894         function login_success($name_value_list = array()){
895                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->login_success');
896                 global $current_language, $sugar_config, $app_strings, $app_list_strings;
897                 $current_language = $sugar_config['default_language'];
898                 if (is_array($name_value_list) && !empty($name_value_list)) {
899                         foreach($name_value_list as $key => $value) {
900                                 if (isset($value['name']) && ($value['name'] == 'language')) {
901                                         $language = $value['value'];
902                                         $supportedLanguages = $sugar_config['languages'];
903                                         if (array_key_exists($language, $supportedLanguages)) {
904                                                 $current_language = $language;
905                                         } // if
906                                 } // if
907                                 if (isset($value['name']) && ($value['name'] == 'notifyonsave')) {
908                                         if ($value['value']) {
909                                                 $_SESSION['notifyonsave'] = true;
910                                         }
911                                 } // if
912                         } // foreach
913                 } else {
914                         if (isset($_SESSION['user_language'])) {
915                                 $current_language = $_SESSION['user_language'];
916                         } // if
917                 }
918                 $GLOBALS['log']->info("Users language is = " . $current_language);
919                 $app_strings = return_application_language($current_language);
920                 $app_list_strings = return_app_list_strings_language($current_language);
921                 $GLOBALS['log']->info('End: SoapHelperWebServices->login_success');
922         } // fn
923
924
925         function checkSaveOnNotify() {
926             $notifyonsave = false;
927             if (isset($_SESSION['notifyonsave']) && $_SESSION['notifyonsave'] == true) {
928                 $notifyonsave = true;
929             } // if
930                 return $notifyonsave;
931         }
932         /*
933          *      Given an account_name, either create the account or assign to a contact.
934          */
935         function add_create_account($seed) {
936                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->add_create_account');
937                 global $current_user;
938                 $account_name = $seed->account_name;
939                 $account_id = $seed->account_id;
940                 $assigned_user_id = $current_user->id;
941
942                 // check if it already exists
943             $focus = new Account();
944             if($focus->ACLAccess('Save')) {
945                         $class = get_class($seed);
946                         $temp = new $class();
947                         $temp->retrieve($seed->id);
948                         if ( empty($account_name) && empty($account_id)) {
949                                 return;
950                         } // if
951                         if (!isset($seed->accounts)){
952                             $seed->load_relationship('accounts');
953                         } // if
954
955                         if($seed->account_name == '' && isset($temp->account_id)){
956                                 $seed->accounts->delete($seed->id, $temp->account_id);
957                                 $GLOBALS['log']->info('End: SoapHelperWebServices->add_create_account');
958                                 return;
959                         }
960                     $arr = array();
961
962             if(!empty($account_id))  // bug # 44280
963             {
964                $query = "select id, deleted from {$focus->table_name} WHERE id='".$seed->db->quote($account_id)."'";
965             }
966             else
967             {
968                $query = "select id, deleted from {$focus->table_name} WHERE name='".$seed->db->quote($account_name)."'";
969             }
970             $result = $seed->db->query($query, true);
971
972                     $row = $seed->db->fetchByAssoc($result, false);
973
974                         // we found a row with that id
975                     if (isset($row['id']) && $row['id'] != -1)
976                     {
977                         // if it exists but was deleted, just remove it entirely
978                         if ( isset($row['deleted']) && $row['deleted'] == 1)
979                         {
980                             $query2 = "delete from {$focus->table_name} WHERE id='". $seed->db->quote($row['id'])."'";
981                             $result2 = $seed->db->query($query2, true);
982                                 }
983                                 // else just use this id to link the contact to the account
984                         else
985                         {
986                                 $focus->id = $row['id'];
987                         }
988                     }
989
990                         // if we didnt find the account, so create it
991                     if (! isset($focus->id) || $focus->id == '')
992                     {
993                         $focus->name = $account_name;
994
995                                 if ( isset($assigned_user_id))
996                                 {
997                            $focus->assigned_user_id = $assigned_user_id;
998                            $focus->modified_user_id = $assigned_user_id;
999                                 }
1000                         $focus->save();
1001                     }
1002
1003                     if($seed->accounts != null && $temp->account_id != null && $temp->account_id != $focus->id){
1004                         $seed->accounts->delete($seed->id, $temp->account_id);
1005                     }
1006
1007                     if(isset($focus->id) && $focus->id != ''){
1008                                 $seed->account_id = $focus->id;
1009                         } // if
1010                         $GLOBALS['log']->info('End: SoapHelperWebServices->add_create_account');
1011
1012             } else {
1013                         $GLOBALS['log']->info('End: SoapHelperWebServices->add_create_account - Insufficient ACLAccess');
1014             } // else
1015         } // fn
1016
1017         function check_for_duplicate_contacts($seed){
1018                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->check_for_duplicate_contacts');
1019                 require_once('modules/Contacts/Contact.php');
1020
1021                 if(isset($seed->id)){
1022                         $GLOBALS['log']->info('End: SoapHelperWebServices->check_for_duplicate_contacts - no duplicte found');
1023                         return null;
1024                 }
1025
1026                 $query = '';
1027
1028                 $trimmed_email = trim($seed->email1);
1029         $trimmed_email2 = trim($seed->email2);
1030             $trimmed_last = trim($seed->last_name);
1031             $trimmed_first = trim($seed->first_name);
1032                 if(!empty($trimmed_email) || !empty($trimmed_email2)){
1033
1034                         //obtain a list of contacts which contain the same email address
1035                         $contacts = $seed->emailAddress->getBeansByEmailAddress($trimmed_email);
1036             $contacts2 = $seed->emailAddress->getBeansByEmailAddress($trimmed_email2);
1037             $contacts = array_merge($contacts, $contacts2);
1038                         if(count($contacts) == 0){
1039                                 $GLOBALS['log']->info('End: SoapHelperWebServices->check_for_duplicate_contacts - no duplicte found');
1040                                 return null;
1041                         }else{
1042                                 foreach($contacts as $contact){
1043                                         if(!empty($trimmed_last) && strcmp($trimmed_last, $contact->last_name) == 0){
1044                                                 if((!empty($trimmed_email) || !empty($trimmed_email2)) && (strcmp($trimmed_email, $contact->email1) == 0 || strcmp($trimmed_email, $contact->email2) == 0 || strcmp($trimmed_email2, $contact->email) == 0 || strcmp($trimmed_email2, $contact->email2) == 0)){
1045                                                         $contact->load_relationship('accounts');
1046                                                         if(empty($seed->account_name) || strcmp($seed->account_name, $contact->account_name) == 0){
1047                                 $GLOBALS['log']->info('End: SoapHelperWebServices->check_for_duplicate_contacts - duplicte found ' . $contact->id);
1048                                                                 return $contact->id;
1049                                                         }
1050                                                 }
1051                                         }
1052                                 }
1053                                 $GLOBALS['log']->info('End: SoapHelperWebServices->check_for_duplicate_contacts - no duplicte found');
1054                                 return null;
1055                         }
1056                 }else
1057                         $GLOBALS['log']->info('End: SoapHelperWebServices->check_for_duplicate_contacts - no duplicte found');
1058                         return null;
1059         }
1060
1061
1062         /**
1063          * decrypt a string use the TripleDES algorithm. This meant to be
1064          * modified if the end user chooses a different algorithm
1065          *
1066          * @param $string - the string to decrypt
1067          *
1068          * @return a decrypted string if we can decrypt, the original string otherwise
1069          */
1070         function decrypt_string($string){
1071                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->decrypt_string');
1072                 if(function_exists('mcrypt_cbc')){
1073                         require_once('modules/Administration/Administration.php');
1074                         $focus = new Administration();
1075                         $focus->retrieveSettings();
1076                         $key = '';
1077                         if(!empty($focus->settings['ldap_enc_key'])){
1078                                 $key = $focus->settings['ldap_enc_key'];
1079                         }
1080                         if(empty($key)) {
1081                                 $GLOBALS['log']->info('End: SoapHelperWebServices->decrypt_string - empty key');
1082                                 return $string;
1083                         } // if
1084                         $buffer = $string;
1085                         $key = substr(md5($key),0,24);
1086                     $iv = "password";
1087                         $GLOBALS['log']->info('End: SoapHelperWebServices->decrypt_string');
1088                     return mcrypt_cbc(MCRYPT_3DES, $key, pack("H*", $buffer), MCRYPT_DECRYPT, $iv);
1089                 }else{
1090                         $GLOBALS['log']->info('End: SoapHelperWebServices->decrypt_string');
1091                         return $string;
1092                 }
1093         } // fn
1094
1095         function isLogLevelDebug() {
1096                 if (isset($GLOBALS['sugar_config']['logger'])) {
1097                         if (isset($GLOBALS['sugar_config']['logger']['level'])) {
1098                                 return ($GLOBALS['sugar_config']['logger']['level'] == 'debug');
1099                         } // if
1100                 }
1101                 return false;
1102         } // fn
1103 } // clazz
1104
1105 ?>