]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - service/v4/SugarWebServiceUtilv4.php
Release 6.5.6
[Github/sugarcrm.git] / service / v4 / SugarWebServiceUtilv4.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37 require_once('service/v3_1/SugarWebServiceUtilv3_1.php');
38
39 class SugarWebServiceUtilv4 extends SugarWebServiceUtilv3_1
40 {
41     function get_module_view_defs($moduleName, $type, $view)
42     {
43         require_once('include/MVC/View/SugarView.php');
44         $metadataFile = null;
45         $results = array();
46         if( empty($moduleName) )
47             return $results;
48
49         $view = strtolower($view);
50         switch (strtolower($type)){
51             case 'default':
52             default:
53                 if ($view == 'subpanel')
54                     $results = $this->get_subpanel_defs($moduleName, $type);
55                 else
56                 {
57                     $v = new SugarView(null,array());
58                     $v->module = $moduleName;
59                     $v->type = $view;
60                     $fullView = ucfirst($view) . 'View';
61                     $metadataFile = $v->getMetaDataFile();
62                     require_once($metadataFile);
63                     if($view == 'list')
64                         $results = $listViewDefs[$moduleName];
65                     else
66                         $results = $viewdefs[$moduleName][$fullView];
67                 }
68         }
69
70         //Add field level acls.
71         $results = $this->addFieldLevelACLs($moduleName,$type, $view, $results);
72
73         return $results;
74     }
75
76
77     /**
78      * Equivalent of get_list function within SugarBean but allows the possibility to pass in an indicator
79      * if the list should filter for favorites.  Should eventually update the SugarBean function as well.
80      *
81      */
82     function get_data_list($seed, $order_by = "", $where = "", $row_offset = 0, $limit=-1, $max=-1, $show_deleted = 0, $favorites = false)
83         {
84                 $GLOBALS['log']->debug("get_list:  order_by = '$order_by' and where = '$where' and limit = '$limit'");
85                 if(isset($_SESSION['show_deleted']))
86                 {
87                         $show_deleted = 1;
88                 }
89                 $order_by=$seed->process_order_by($order_by, null);
90
91                 $params = array();
92                 if(!empty($favorites)) {
93                   $params['favorites'] = true;
94                 }
95
96                 $query = $seed->create_new_list_query($order_by, $where,array(),$params, $show_deleted);
97                 return $seed->process_list_query($query, $row_offset, $limit, $max, $where);
98         }
99
100         /**
101      * Convert modules list to Web services result
102      *
103      * @param array $list List of module candidates (only keys are used)
104      * @param array $availModules List of module availability from Session
105      */
106     public function getModulesFromList($list, $availModules)
107     {
108         global $app_list_strings;
109         $enabled_modules = array();
110         $availModulesKey = array_flip($availModules);
111         foreach ($list as $key=>$value)
112         {
113             if( isset($availModulesKey[$key]) )
114             {
115                 $label = !empty( $app_list_strings['moduleList'][$key] ) ? $app_list_strings['moduleList'][$key] : '';
116                     $acl = $this->checkModuleRoleAccess($key);
117                     $fav = $this->is_favorites_enabled($key);
118                     $enabled_modules[] = array('module_key' => $key,'module_label' => $label, 'favorite_enabled' => $fav, 'acls' => $acl);
119             }
120         }
121         return $enabled_modules;
122     }
123
124     /**
125      * Return a boolean indicating if the bean name is favorites enabled.
126      *
127      * @param string The module name
128      * @return bool true indicating bean is favorites enabled
129      */
130     function is_favorites_enabled($module_name)
131     {
132         global $beanList, $beanFiles;
133
134         $fav = FALSE;
135         return $fav;
136     }
137
138
139         /**
140          * Processes the filter_fields attribute to use with SugarBean::create_new_list_query()
141          *
142          * @param object $value SugarBean
143          * @param array $fields
144          * @return array
145          */
146     protected function filter_fields_for_query(SugarBean $value, array $fields)
147     {
148         $GLOBALS['log']->info('Begin: SoapHelperWebServices->filter_fields_for_query');
149         $filterFields = array();
150         foreach($fields as $field)
151         {
152             if (isset($value->field_defs[$field]))
153             {
154                 $filterFields[$field] = $value->field_defs[$field];
155             }
156         }
157         $GLOBALS['log']->info('End: SoapHelperWebServices->filter_fields_for_query');
158         return $filterFields;
159     }
160
161     function get_field_list($value,$fields,  $translate=true) {
162
163             $GLOBALS['log']->info('Begin: SoapHelperWebServices->get_field_list(too large a struct, '.print_r($fields, true).", $translate");
164                 $module_fields = array();
165                 $link_fields = array();
166                 if(!empty($value->field_defs)){
167
168                         foreach($value->field_defs as $var){
169                                 if(!empty($fields) && !in_array( $var['name'], $fields))continue;
170                                 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;
171                                 if ((isset($var['source']) && $var['source'] == 'non_db') && (isset($var['type']) && $var['type'] != 'link')) {
172                                         continue;
173                                 }
174                                 $required = 0;
175                                 $options_dom = array();
176                                 $options_ret = array();
177                                 // Apparently the only purpose of this check is to make sure we only return fields
178                                 //   when we've read a record.  Otherwise this function is identical to get_module_field_list
179                                 if( isset($var['required']) && ($var['required'] || $var['required'] == 'true' ) ){
180                                         $required = 1;
181                                 }
182
183                                 if($var['type'] == 'bool')
184                                     $var['options'] = 'checkbox_dom';
185
186                                 if(isset($var['options'])){
187                                         $options_dom = translate($var['options'], $value->module_dir);
188                                         if(!is_array($options_dom)) $options_dom = array();
189                                         foreach($options_dom as $key=>$oneOption)
190                                                 $options_ret[$key] = $this->get_name_value($key,$oneOption);
191                                 }
192
193                     if(!empty($var['dbType']) && $var['type'] == 'bool') {
194                         $options_ret['type'] = $this->get_name_value('type', $var['dbType']);
195                     }
196
197                     $entry = array();
198                     $entry['name'] = $var['name'];
199                     $entry['type'] = $var['type'];
200                     $entry['group'] = isset($var['group']) ? $var['group'] : '';
201                     $entry['id_name'] = isset($var['id_name']) ? $var['id_name'] : '';
202
203                     if ($var['type'] == 'link') {
204                             $entry['relationship'] = (isset($var['relationship']) ? $var['relationship'] : '');
205                             $entry['module'] = (isset($var['module']) ? $var['module'] : '');
206                             $entry['bean_name'] = (isset($var['bean_name']) ? $var['bean_name'] : '');
207                                         $link_fields[$var['name']] = $entry;
208                     } else {
209                             if($translate) {
210                                 $entry['label'] = isset($var['vname']) ? translate($var['vname'], $value->module_dir) : $var['name'];
211                             } else {
212                                 $entry['label'] = isset($var['vname']) ? $var['vname'] : $var['name'];
213                             }
214                             $entry['required'] = $required;
215                             $entry['options'] = $options_ret;
216                             $entry['related_module'] = (isset($var['id_name']) && isset($var['module'])) ? $var['module'] : '';
217                             $entry['calculated'] =  (isset($var['calculated']) && $var['calculated']) ? true : false;
218                     $entry['len'] =  isset($var['len']) ? $var['len'] : '';
219
220                                         if(isset($var['default'])) {
221                                            $entry['default_value'] = $var['default'];
222                                         }
223                                         if( $var['type'] == 'parent' && isset($var['type_name']) )
224                                            $entry['type_name'] = $var['type_name'];
225
226                                         $module_fields[$var['name']] = $entry;
227                     } // else
228                         } //foreach
229                 } //if
230
231                 if($value->module_dir == 'Meetings' || $value->module_dir == 'Calls')
232                 {
233                     if( isset($module_fields['duration_minutes']) && isset($GLOBALS['app_list_strings']['duration_intervals']))
234                     {
235                         $options_dom = $GLOBALS['app_list_strings']['duration_intervals'];
236                         $options_ret = array();
237                         foreach($options_dom as $key=>$oneOption)
238                                                 $options_ret[$key] = $this->get_name_value($key,$oneOption);
239
240                         $module_fields['duration_minutes']['options'] = $options_ret;
241                     }
242                 }
243
244                 if($value->module_dir == 'Bugs'){
245                         require_once('modules/Releases/Release.php');
246                         $seedRelease = new Release();
247                         $options = $seedRelease->get_releases(TRUE, "Active");
248                         $options_ret = array();
249                         foreach($options as $name=>$value){
250                                 $options_ret[] =  array('name'=> $name , 'value'=>$value);
251                         }
252                         if(isset($module_fields['fixed_in_release'])){
253                                 $module_fields['fixed_in_release']['type'] = 'enum';
254                                 $module_fields['fixed_in_release']['options'] = $options_ret;
255                         }
256             if(isset($module_fields['found_in_release'])){
257                 $module_fields['found_in_release']['type'] = 'enum';
258                 $module_fields['found_in_release']['options'] = $options_ret;
259             }
260                         if(isset($module_fields['release'])){
261                                 $module_fields['release']['type'] = 'enum';
262                                 $module_fields['release']['options'] = $options_ret;
263                         }
264                         if(isset($module_fields['release_name'])){
265                                 $module_fields['release_name']['type'] = 'enum';
266                                 $module_fields['release_name']['options'] = $options_ret;
267                         }
268                 }
269
270                 if(isset($value->assigned_user_name) && isset($module_fields['assigned_user_id'])) {
271                         $module_fields['assigned_user_name'] = $module_fields['assigned_user_id'];
272                         $module_fields['assigned_user_name']['name'] = 'assigned_user_name';
273                 }
274                 if(isset($value->assigned_name) && isset($module_fields['team_id'])) {
275                         $module_fields['team_name'] = $module_fields['team_id'];
276                         $module_fields['team_name']['name'] = 'team_name';
277                 }
278                 if(isset($module_fields['modified_user_id'])) {
279                         $module_fields['modified_by_name'] = $module_fields['modified_user_id'];
280                         $module_fields['modified_by_name']['name'] = 'modified_by_name';
281                 }
282                 if(isset($module_fields['created_by'])) {
283                         $module_fields['created_by_name'] = $module_fields['created_by'];
284                         $module_fields['created_by_name']['name'] = 'created_by_name';
285                 }
286
287                 $GLOBALS['log']->info('End: SoapHelperWebServices->get_field_list');
288                 return array('module_fields' => $module_fields, 'link_fields' => $link_fields);
289         }
290
291
292         function new_handle_set_entries($module_name, $name_value_lists, $select_fields = FALSE) {
293                 $GLOBALS['log']->info('Begin: SoapHelperWebServices->new_handle_set_entries');
294                 global $beanList, $beanFiles, $current_user, $app_list_strings;
295
296                 $ret_values = array();
297
298                 $class_name = $beanList[$module_name];
299                 require_once($beanFiles[$class_name]);
300                 $ids = array();
301                 $count = 1;
302                 $total = sizeof($name_value_lists);
303                 foreach($name_value_lists as $name_value_list){
304                         $seed = new $class_name();
305
306                         $seed->update_vcal = false;
307                         foreach($name_value_list as $name => $value){
308                                 if(is_array($value) &&  $value['name'] == 'id'){
309                     $seed->retrieve($value['value']);
310                     break;
311                 }
312                 else if($name === 'id' ){
313                     $seed->retrieve($value);
314                 }
315                         }
316
317                         foreach($name_value_list as $name => $value) {
318                             //Normalize the input
319                                 if(!is_array($value)){
320                     $field_name = $name;
321                     $val = $value;
322                 }
323                 else{
324                     $field_name = $value['name'];
325                     $val = $value['value'];
326                 }
327
328                                 if($seed->field_name_map[$field_name]['type'] == 'enum'){
329                                         $vardef = $seed->field_name_map[$field_name];
330                                         if(isset($app_list_strings[$vardef['options']]) && !isset($app_list_strings[$vardef['options']][$val]) ) {
331                                                 if ( in_array($val,$app_list_strings[$vardef['options']]) ){
332                                                         $val = array_search($val,$app_list_strings[$vardef['options']]);
333                                                 }
334                                         }
335                                 }
336                                 if($module_name == 'Users' && !empty($seed->id) && ($seed->id != $current_user->id) && $field_name == 'user_hash'){
337                                         continue;
338                                 }
339                                 if(!empty($seed->field_name_map[$field_name]['sensitive'])) {
340                                         continue;
341                                 }
342                                 $seed->$field_name = $val;
343                         }
344
345                         if($count == $total){
346                                 $seed->update_vcal = false;
347                         }
348                         $count++;
349
350                         //Add the account to a contact
351                         if($module_name == 'Contacts'){
352                                 $GLOBALS['log']->debug('Creating Contact Account');
353                                 $this->add_create_account($seed);
354                                 $duplicate_id = $this->check_for_duplicate_contacts($seed);
355                                 if($duplicate_id == null){
356                                         if($seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
357                                                 $seed->save();
358                                                 if($seed->deleted == 1){
359                                                         $seed->mark_deleted($seed->id);
360                                                 }
361                                                 $ids[] = $seed->id;
362                                         }
363                                 }
364                                 else{
365                                         //since we found a duplicate we should set the sync flag
366                                         if( $seed->ACLAccess('Save')){
367                                                 $seed = new $class_name();
368                                                 $seed->id = $duplicate_id;
369                                                 $seed->contacts_users_id = $current_user->id;
370                                                 $seed->save();
371                                                 $ids[] = $duplicate_id;//we have a conflict
372                                         }
373                                 }
374                         }
375                         else if($module_name == 'Meetings' || $module_name == 'Calls'){
376                                 //we are going to check if we have a meeting in the system
377                                 //with the same outlook_id. If we do find one then we will grab that
378                                 //id and save it
379                                 if( $seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
380                                         if(empty($seed->id) && !isset($seed->id)){
381                                                 if(!empty($seed->outlook_id) && isset($seed->outlook_id)){
382                                                         //at this point we have an object that does not have
383                                                         //the id set, but does have the outlook_id set
384                                                         //so we need to query the db to find if we already
385                                                         //have an object with this outlook_id, if we do
386                                                         //then we can set the id, otherwise this is a new object
387                                                         $order_by = "";
388                                                         $query = $seed->table_name.".outlook_id = '".$seed->outlook_id."'";
389                                                         $response = $seed->get_list($order_by, $query, 0,-1,-1,0);
390                                                         $list = $response['list'];
391                                                         if(count($list) > 0){
392                                                                 foreach($list as $value)
393                                                                 {
394                                                                         $seed->id = $value->id;
395                                                                         break;
396                                                                 }
397                                                         }//fi
398                                                 }//fi
399                                         }//fi
400                                     if (empty($seed->reminder_time)) {
401                         $seed->reminder_time = -1;
402                     }
403                     if($seed->reminder_time == -1){
404                         $defaultRemindrTime = $current_user->getPreference('reminder_time');
405                         if ($defaultRemindrTime != -1){
406                             $seed->reminder_checked = '1';
407                             $seed->reminder_time = $defaultRemindrTime;
408                         }
409                     }
410                                         $seed->save();
411                                         if($seed->deleted == 1){
412                                                 $seed->mark_deleted($seed->id);
413                                         }
414                                         $ids[] = $seed->id;
415                                 }//fi
416                         }
417                         else
418                         {
419                                 if( $seed->ACLAccess('Save') && ($seed->deleted != 1 || $seed->ACLAccess('Delete'))){
420                                         $seed->save();
421                                         $ids[] = $seed->id;
422                                 }
423                         }
424
425                         // if somebody is calling set_entries_detail() and wants fields returned...
426                         if ($select_fields !== FALSE) {
427                                 $ret_values[$count] = array();
428
429                                 foreach ($select_fields as $select_field) {
430                                         if (isset($seed->$select_field)) {
431                                                 $ret_values[$count][$select_field] = $this->get_name_value($select_field, $seed->$select_field);
432                                         }
433                                 }
434                         }
435                 }
436
437                 // handle returns for set_entries_detail() and set_entries()
438                 if ($select_fields !== FALSE) {
439                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_entries');
440                         return array(
441                                 'name_value_lists' => $ret_values,
442                         );
443                 }
444                 else {
445                         $GLOBALS['log']->info('End: SoapHelperWebServices->new_handle_set_entries');
446                         return array(
447                                 'ids' => $ids,
448                         );
449                 }
450         }
451
452
453     function checkSessionAndModuleAccess($session, $login_error_key, $module_name, $access_level, $module_access_level_error_key, $errorObject)
454     {
455           if(isset($_REQUEST['oauth_token'])) {
456               $session = $this->checkOAuthAccess($errorObject);
457           }
458           if(!$session) return false;
459           return parent::checkSessionAndModuleAccess($session, $login_error_key, $module_name, $access_level, $module_access_level_error_key, $errorObject);
460     }
461
462     public function checkOAuthAccess($errorObject)
463     {
464         require_once "include/SugarOAuthServer.php";
465         try {
466                 $oauth = new SugarOAuthServer();
467                 $token = $oauth->authorizedToken();
468                 if(empty($token) || empty($token->assigned_user_id)) {
469                     return false;
470                 }
471         } catch(OAuthException $e) {
472             $GLOBALS['log']->debug("OAUTH Exception: $e");
473             $errorObject->set_error('invalid_login');
474                         $this->setFaultObject($errorObject);
475             return false;
476         }
477
478             $user = new User();
479             $user->retrieve($token->assigned_user_id);
480             if(empty($user->id)) {
481                 return false;
482             }
483         global $current_user;
484                 $current_user = $user;
485                 ini_set("session.use_cookies", 0); // disable cookies to prevent session ID from going out
486                 session_start();
487                 session_regenerate_id();
488                 $_SESSION['oauth'] = $oauth->authorization();
489                 $_SESSION['avail_modules'] = $this->get_user_module_list($user);
490                 // TODO: handle role
491                 // handle session
492                 $_SESSION['is_valid_session']= true;
493                 $_SESSION['ip_address'] = query_client_ip();
494                 $_SESSION['user_id'] = $current_user->id;
495                 $_SESSION['type'] = 'user';
496                 $_SESSION['authenticated_user_id'] = $current_user->id;
497         return session_id();
498     }
499
500
501     /**
502      * get_subpanel_defs
503      *
504      * @param String $module The name of the module to get the subpanel definition for
505      * @param String $type The type of subpanel definition ('wireless' or 'default')
506      * @return array Array of the subpanel definition; empty array if no matching definition found
507      */
508         function get_subpanel_defs($module, $type)
509         {
510             global $beanList, $beanFiles;
511             $results = array();
512             switch ($type)
513             {
514                 case 'wireless':
515
516                 if (file_exists('custom/modules/'.$module.'/metadata/wireless.subpaneldefs.php'))
517                          require_once('custom/modules/'.$module.'/metadata/wireless.subpaneldefs.php');
518                     else if (file_exists('modules/'.$module.'/metadata/wireless.subpaneldefs.php'))
519                          require_once('modules/'.$module.'/metadata/wireless.subpaneldefs.php');
520
521                 //If an Ext/WirelessLayoutdefs/wireless.subpaneldefs.ext.php file exists, then also load it as well
522                 if(file_exists('custom/modules/'.$module.'/Ext/WirelessLayoutdefs/wireless.subpaneldefs.ext.php'))
523                 {
524                     require_once('custom/modules/'.$module.'/Ext/WirelessLayoutdefs/wireless.subpaneldefs.ext.php');
525                 }
526                     break;
527
528                 case 'default':
529                 default:
530                     if (file_exists ('modules/'.$module.'/metadata/subpaneldefs.php' ))
531                         require ('modules/'.$module.'/metadata/subpaneldefs.php');
532                     if ( file_exists('custom/modules/'.$module.'/Ext/Layoutdefs/layoutdefs.ext.php' ))
533                         require ('custom/modules/'.$module.'/Ext/Layoutdefs/layoutdefs.ext.php');
534             }
535
536             //Filter results for permissions
537             foreach ($layout_defs[$module]['subpanel_setup'] as $subpanel => $subpaneldefs)
538             {
539                 $moduleToCheck = $subpaneldefs['module'];
540                 if(!isset($beanList[$moduleToCheck]))
541                    continue;
542                 $class_name = $beanList[$moduleToCheck];
543                 $bean = new $class_name();
544                 if($bean->ACLAccess('list'))
545                     $results[$subpanel] = $subpaneldefs;
546             }
547
548             return $results;
549
550         }
551 }