SuiteCRM-Core/service/v3/SugarWebServiceImplv3.php
Dillon-Brown 114b895b6d Squashed 'public/legacy/' changes from 2aaee3c558..7ce0eaf560
7ce0eaf560 Merge commit 'a9b7e9d38c89bb831eed5c46ae88e1a340a9e745' into refactor_legacy
77175ae5ca Fix undefined property sentAssignmentNotifications
a12d18b3c9 Update CleanCSVTest
ed7951dc93 Update Composer
21c3adc06f SuiteCRM 7.11.21 Release
d6aa88abd2 Allow filtering Survey campaigns
7ab8113825 Adding new attribute to CaseTest for sentAssignmentNotification as well as other Tests
3b13d3d4ac Retrieve SuiteCRM version in get_server_info
db739a3116 Improve Contacts duplicates list
1ebfecf604 Help text containing quotes is not correctly displayed
9191047355 Wrong spelling of AOR_Reports module
e3aa666d15 fix for #8991
0ae8676656 Link fix to documentation site
e6bcec88cb Notes for abbreviations, VAT, Activity Stream, SAML
d2a0f08ab9 Indentation fix
9602a5ab9f Space typo fix
6105f4b231 Moving comment next to the string
49be1068b5 https url fix
85a3dfb122 SuiteP template translators notes
6025f859e4 Fix for: #9179 AOR_Charts getShortenedLabel fails on utf8 characters
092ab1f7fa Add the ability import Projects
a91fe3995e Fix Issue #4145
5d077d44e2 Fix #9205 - Duplicate audit records.
925f194db2 Fix #9203 - Duplicate notification emails.
16f6fda636 Fix Archive Folder Query
504f16f0a8 Add cases to email object_arr
fe07e1660c Fix only init Currency once
5692da9269 Fix broken image path in reports HTML
ce93d319d7  Fix php notices
013e0eee39 Change pdfheader/pdffooter data type to longtext
175df9ffe9 Set default perms on new log file
4caedf2fdf Update CaseUpdatesHook.php
8d4678fdb1 Remove spaces in fnc call ACLController::filterModuleList()
1e5e8bfecc Fix function declaration of TabController::get_key_array()
9e85083916 Wrong spelling of ProspectLists module
ce8f3b0665 Fix #9201 - Filter form label styling.
568839d1bd Fix #9237 where dates in aow actions & conditions are not saved or displayed correctly
17363c3f60 Fix #6997 - User profile password auto-fill
5b87663738 Correct layout of date fields
1de52dc97d 7.11.20
6737e71506 Fix Users index incompatible with MSSQL
bd9dd96f3a Change populateDefaultValues fatal log on empty field_defs to warning
9039d97b07 Fix theme display issues
ffb434042f Fix Missing locale in FullCalender 3.10
32e8146664 Fix Php compatibility within Admin ConfigureTabs
e0904414a1 Fix Email Address loading performance
fdea144ecb Fix #8319 - Multiple IMAP Inboxes fails to display emails
45a6527e91 Fix #7285 - Allow filter of custom fields on V8 API Get Modules
55dab76a1a Fix #8420 - V8 API issues fails on windows
8994449ef8 Upgrade ElasticSearch to v7.x
cd2e17a49a Implement PDFEngine
1a50079341 Fix PDF_Lib constructors
17035aa25b Replace deprecated fzaninotto/faker with fakerphp/faker
854daa3ef7 Move test namespaces into autoload-dev
a801513237 Upgrade nesbot/carbon to v2.x
889e73b943 Update Travis config to use composer v2.x
22f956cf74 Upgrade composer-merge-plugin to v2.x
753e6242fa Fix PHPUnit 9 deprecations and warnings
f62d8d7bed Fix test case class not matching filename deprecation warnings
1b4cefb5c3 Replace abandoned leafo/scssphp with scssphp/scssphp
53a1cf3765 Upgrade Robo to v3.x
32231c4f1d Update composer.json
5b8ea6cd49 Fix missing default config values
2555dc14b7 Consolidate global search settings
12d51f8e5c Remove duplicate "Global Search" link in the adminpanel
6c28c687ee Implement search engine selection
24a3e9d6c2 Deprecate UnifiedSearchAdvanced
6453ebf25c Unify search engines
a740042295 Remove new/legacy search engine labels
dc8a8bc8e1 Add codeception 4.1.x dependencies to composer
8404643044 Migrate PHPUnit schema for 9.5.x
ac144b8dfc Upgrade PHPUnit to 9.5.x
2f7e5790bc Remove codeception
4882f9531e Fix tests remove incompletes
74596e24b8 Fix tests deprecated asserts
8539246027 Fix tests define return type hints
ff8e2f2973 Update test namespaces for PSR-4/PSR-8
5f17109ce4 Fix tests redundant noinspection
65fa1662d2 Fix tests misordered assert arguments
d3d589c4fc Fix tests use appropriate asserts
f1c8e05d00 Fix tests one-time use variables
fad98fcead Fix tests method invocations
e660423312 Update PHPUnit schema
251bf18f31 Update Travis config to remove PHP 7.2
a715d7120c Update minimum required PHP to v7.3.0
369cd99c3a Fix #9106 - Update securexss for backwards compatibility
b1263f189f Update composer
42c065dd91 7.11.19
cdc3b47207 Fix Calender display issues in FullCalender 3.10
3caa17e1f8 Fix #7999 - Prevent securitygroups mass assign damage
df0c687ad0 Fix #5624 - Make SWSPEditRoleButton::displayList compatible w. parent
a173f1b1d2 Fix #8571 - Remove duplicate code in users detailviewdefs
4e3c62fe56 Fix #8514 - Implement effective opcache file clearing
afca8fa5f8 Fix #8461, #8462 - PHP files are potentially overwritten
5b0f1f13ed Fix #8700 - Various problems in PHPDocs throughout the codebase.
f89f115fe6 Fix #9067 - Fix the drop down width
579b894f65 Add Additional api filter option `like`
88316f8612 Add filters in relationship API
277b9e5520 Add Relationship Beans in V8 API Response
e178ef8495 Fix #9090 - User menu alignment
631c756fc0 Fix #6051 - Modulebuilder labels edit fixes
2c2b5e689b Update JQuery JS Library to v3.6.0
065306623d Update FullCalendar JS Library to v3.10.2
0634e7f533 Update YUI JS Library to 2.9.1
a74ccf7eae Fix #8999 - Hardcoded 'by' label in calls
c8f6cd9061 Fix #9034 - Business Hours does not work in non-english languages
e554511cb0 Fix #8910 - Update the V8 Api to allow for upload of documents similar to notes
ef590862fb Fix #9010 - Add missing 'view task' label on calendar
b339312d79 Fix #8894 - Add missing label for calendar dashlet
f936a6366a Fix #9032 - Prevent Notice Error During Import
42f87aac1d Fix #8182 - Update updateTimeDateFields to handle undefined dates
a744e89bf6 Fix #9075 - Removing deleted related beans via link
b17ef78ced Fix #8988 - Improve upon solution which doesn't cache incomplete beans
315c1ecf63 Fix #7772 - Only index ElasticSearch when enabled
7c05a09d90 Fix #9101 LangText exception breaking ElasticSearch
2bad09d0c0 Fix #8472 - No or not complete Searchresults using elasticsearch engine
6978a22cb1 Fix #6800 - Elasticsearch: Elastic index name is hardcoded
cf8b487e6d Fix #8916 - Misspelled elasticsearch labels
8029916390 Fix #9080 - Update config for google/apiclient at composer.json
318d91a15c Fix #9060 - Project Form action should not be changed if delete is not confirmed
b68834c47b Fix #8676 - New Scheduled Reports does not run
d87c7a0748 Fix #2645 - Calendar quick create ignores required fields
91e9d7540a Deprecate PdfParser
a1ee531f3d Deprecate advanced open discovery (AOD)
122b872c2b Fix subpanel insights to support function query
f2b6be56e2 [Legacy] Update list count query to accept alias name
932d700511 [Legacy] Admin Release Styling Fixes
e13201af39 [Legacy] Quotes & Invoices Faint Line Removed
1f0fdf0fb1 [Legacy] History Subpanel Styling Changes
a01fe52c40 [Legacy] Date Calendar Icon Color Fixes
c84dc60a1c [Legacy] Fix Add Dashlet Tab via Enter Key in Home Page Redirects to Legacy
3ea774916c [Legacy] Make anchor links within Convert Lead module point to S8
290978a5d3 [Legacy] add language labels for user auth guard ACL Error Messages
8d0ccd3ddf create user auth guard backend handler to handle User ACL
377e85090c [Legacy] Scrollbar color fix globally
e776c38c42 [Legacy] Action DropDown Arrow Alignment Fixes
bc384c226e Border Outline Color Fixes
811df34b1f [Legacy] Add utility method to retrieve install languages
39f3629b08 [Legacy] Add labels
e6388fa338 [Legacy] Configure Module Menu Styling Changes
5653a6904a [Legacy] - Increment suitecrm_version.php
95073941fa [Legacy] Add labels
5597e87745 [Legacy] Add EmailAddressLinkMapper to ApiBeanMapper
17e9e91d04 [Legacy] Add LineItemSaveHandler
366dc162e0 [Legacy] Add BeanSaveHandlers
5e38fc88d8 [Legacy] Rename Modules Styling Changes
3bb5a5d6a9 Merge commit '9c71e8c884' into fix/legacy_update
8b45c9a338 [Legacy] Fix Display Module & Subpanel Styling
85d70377d1 [Legacy] Add line item single primary email validation label
da4a6a6c40 [Legacy] Add labels
b80198be11 [Legacy] Add labels
56637aa080 Refactor filter content ApiBeanMapper to use filter mapper
bee6f9c10b [Legacy] Move Legacy Filter Mapper to legacy
6ac12e5bd4 [Legacy] Fix Campaign Email Settings Styling
0aff61bc38 [Legacy] System Settings Hover Button Changes
b9194c1c66 [Legacy] Activity Stream Styling Changes
37b80cefd6 [Legacy] Admin Language Styling Changes
ec53218574 [Legacy] Fix Theme Setting Styling Changes
951e1ae844 [Legacy] Update SugarBean to support custom union query for history timeline widget
49c754ed87 Update history timeline backend handler to handle activities and audit data along with history data
4807b6fa45 [Legacy] Add labels for history timeline widget
174bba1e38 [Legacy] Fix Admin Diagnostic Tool Styling Changes
b10a2d7e26 [Legacy] Fix Button Hover Styling
631cbbbe0e [Leagcy] Workflow & Invoice & Quotes Line Items Styling Fix
ec22f577c9 [Legacy] Fix Help Icon Styling
9a092d2d51 [Legacy] Fix Security Groups Create Styling
96dda062d2 [Legacy] Fix Security Suite Settings Styling
ed05b461aa [Legacy] Dashboard modal dashlet & add tab & edit tab
2b741a982a [Legacy] Fix Role List User Styling
b2abf4588c [Legacy] Fix AOP Settings Styling
763d0ed66b [Legacy] Dashlet Table Scroll Fixes
aa2aebfa82 [Legacy] Add attribute array mapping to ApiBeanMapper
b8e3926ace [Legacy] Add MassUpdatePort
327ddf764d [Legacy] Add labels
d10884fbad [Legacy] Fix Outline Border color
0d08b6684b [Legacy] Add Post Upgrade port service
de0ebec1d4 [Legacy] Fix Business Hours Styling
a69aa7f89b [Legacy] Fix AOS Settings Styling
942b635996 [Legacy] iFrame Modal Page Styling Changes
95c4d8a89a [Legacy] Admin Locale Styling Changes
4b4aade088 [Legacy] Role CreateView Styling Changes
4b8082c1b0 [Legacy] Password Management Styling Changes
f542903e46 [Legacy] Currency Recordview styling changes
0efba176b7 [Legacy] Email Settings Send Email Styling Changes
f8aad710e1 [Legacy] Email Settings Styling Changes
3e41d46bc6 [Legacy] Changes to support Legacy integration of Merge Duplicates action to Suite8
254619ad37 [Legacy] Roles Management Styling Changes
2ac0e9f126 [Legacy] Add legacy portability services to add records or contacts to a target list
42a1ab8e88 [Legacy] Add labels for add to target list messages
8933416dc2 [Legacy] Dashboard Settings ModalPopup Changes
157ce24459 [Legacy] Project Resource Calendar Styling Changes
86b806d990 [Legacy] System Settings CSS Changes
80e5ce0e5e [Legacy] Add Language Label Change Log
b2e9a36e6a [Legacy] Increment suitecrm_version
af1d13f4a6 Merge commit '2473298dc6' into beta2
039df6a308 [Legacy] Add Legacy portability Link Service
cde96fd758 [Legacy] Change Case update wiget items display
8ee998700d [Legacy] Add generic action success label
357655058c [Legacy] Change Cases calculated field rules
49120c6a05 [Legacy] Add non-db source field to cases
6f9cc072db [Legacy] Add null checks to CaseUpdate sendUpdate
cc68ead8ca [Legacy] Remove case threads from case detailviewdefs
b651151cc9 [Legacy] Add case updates widget configuration
5960f06d73 [Legacy] Add record-thread component related labels
2824f62499 [Legacy] Add case updates api bean mappers
7244666094 [Legacy] Add non-db author field to case updates
19e839e022 [Legacy] Add case thread update label
eae9e509f6 define datetime format conversion mappers for datetimecombo field
48ff651d60 [Legacy] Inbound Email ListView Styling Changes
144a01f3c7 [Legacy] Add link label
9a3bbaec3f [Legacy] Labels definition for link entity relationship via record subpanels
1c7b7d1770 [Legacy] Update unlink related labels
79088c678c [Legacy] Add unlink service port
7495fa6d86 [Legacy] Changes for Unlink Subpanel Relationship
c8df2643cf [Legacy] User Profile Styling Changes
ce539098dd [Legacy] Homepage Mobile Changes
22c6e4736e [Legacy] Add Saved filter related labels
6971d34c2c [Legacy] Add SavedSearch module metadata
5a70355c52 [Legacy] Add api to bean mapping handling to ApiBeanMapper
e1a94f7cd1 [Legacy] Add null check to SavedSearch bean
e37dbf171b [Legacy] Add SavedSearch module api bean mappers
a441ec08ef [Legacy] Add ApiBeanModuleMappers
913cce923f Search Bar Mobile Changes
ee1593f735 [Legacy] Remove advanced open discovery (AOD)
8f60fafec3 [Legacy] Define a new function to return all columns defined for the module list view
ead86f0d02 [Legacy] Convert Lead Styling Changes
5606baede5 [Legacy] Subpanel Design Changes
7bf0e84681 [Legacy] Tab Arrwo Misalignment Changes
6a03cc65f2 [Legacy] Inbound Email Styling Changes
784f089a90 [Legacy] Update legacy vendor pathing
aa1e3d8c59 [Legacy] Remove legacy composer
9e990b8ce7 [Legacy] Add global labels for listView Column Selector

git-subtree-dir: public/legacy
git-subtree-split: 7ce0eaf560b55293ca3f105ac776ff936b319679
2021-08-30 10:17:18 +01:00

656 lines
35 KiB
PHP
Executable file

<?php
if (!defined('sugarEntry')) {
define('sugarEntry', true);
}
/**
*
* SugarCRM Community Edition is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
*
* SuiteCRM is an extension to SugarCRM Community Edition developed by SalesAgility Ltd.
* Copyright (C) 2011 - 2018 SalesAgility Ltd.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
* reasonably feasible for technical reasons, the Appropriate Legal Notices must
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
*/
/**
* This class is an implementation class for all the rest services
*/
require_once('service/core/SugarWebServiceImpl.php');
require_once('SugarWebServiceUtilv3.php');
class SugarWebServiceImplv3 extends SugarWebServiceImpl
{
public function __construct()
{
self::$helperObject = new SugarWebServiceUtilv3();
}
/**
* Log the user into the application
*
* @param UserAuth array $user_auth -- Set user_name and password (password needs to be
* in the right encoding for the type of authentication the user is setup for. For Base
* sugar validation, password is the MD5 sum of the plain text password.
* @param String $application -- The name of the application you are logging in from. (Currently unused).
* @param array $name_value_list -- Array of name value pair of extra parameters. As of today only 'language' and 'notifyonsave' is supported
* @return Array - id - String id is the session_id of the session that was created.
* - module_name - String - module name of user
* - name_value_list - Array - The name value pair of user_id, user_name, user_language, user_currency_id, user_currency_name,
* - user_default_team_id, user_is_admin, user_default_dateformat, user_default_timeformat
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function login($user_auth, $application, $name_value_list)
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->login');
global $sugar_config, $system_config;
$error = new SoapError();
$user = BeanFactory::newBean('Users');
$success = false;
if (!empty($user_auth['encryption']) && $user_auth['encryption'] === 'PLAIN') {
$user_auth['password'] = md5($user_auth['password']);
}
//rrs
$system_config = BeanFactory::newBean('Administration');
$system_config->retrieveSettings('system');
$authController = new AuthenticationController();
//rrs
$isLoginSuccess = $authController->login($user_auth['user_name'], $user_auth['password'], array('passwordEncrypted' => true));
$usr_id=$user->retrieve_user_id($user_auth['user_name']);
if ($usr_id) {
$user->retrieve($usr_id);
}
if ($isLoginSuccess) {
if ($_SESSION['hasExpiredPassword'] =='1') {
$error->set_error('password_expired');
$GLOBALS['log']->fatal('password expired for user ' . $user_auth['user_name']);
LogicHook::initialize();
$GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
self::$helperObject->setFaultObject($error);
return;
}
if (!empty($user) && !empty($user->id) && !$user->is_group) {
$success = true;
global $current_user;
$current_user = $user;
}
} elseif ($usr_id && isset($user->user_name) && ($user->getPreference('lockout') == '1')) {
$error->set_error('lockout_reached');
$GLOBALS['log']->fatal('Lockout reached for user ' . $user_auth['user_name']);
LogicHook::initialize();
$GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
self::$helperObject->setFaultObject($error);
return;
} elseif (function_exists('openssl_decrypt')) {
$password = self::$helperObject->decrypt_string($user_auth['password']);
if ($authController->login($user_auth['user_name'], $password) && isset($_SESSION['authenticated_user_id'])) {
$success = true;
}
}
if ($success) {
session_start();
global $current_user;
//$current_user = $user;
self::$helperObject->login_success($name_value_list);
$current_user->loadPreferences();
$_SESSION['is_valid_session']= true;
$_SESSION['ip_address'] = query_client_ip();
$_SESSION['user_id'] = $current_user->id;
$_SESSION['type'] = 'user';
$_SESSION['avail_modules']= self::$helperObject->get_user_module_list($current_user);
$_SESSION['authenticated_user_id'] = $current_user->id;
$_SESSION['unique_key'] = $sugar_config['unique_key'];
$current_user->call_custom_logic('after_login');
$GLOBALS['log']->info('End: SugarWebServiceImpl->login - successful login');
$nameValueArray = array();
global $current_language;
$nameValueArray['user_id'] = self::$helperObject->get_name_value('user_id', $current_user->id);
$nameValueArray['user_name'] = self::$helperObject->get_name_value('user_name', $current_user->user_name);
$nameValueArray['user_language'] = self::$helperObject->get_name_value('user_language', $current_language);
$cur_id = $current_user->getPreference('currency');
$nameValueArray['user_currency_id'] = self::$helperObject->get_name_value('user_currency_id', $cur_id);
$nameValueArray['user_is_admin'] = self::$helperObject->get_name_value('user_is_admin', is_admin($current_user));
$nameValueArray['user_default_team_id'] = self::$helperObject->get_name_value('user_default_team_id', $current_user->default_team);
$nameValueArray['user_default_dateformat'] = self::$helperObject->get_name_value('user_default_dateformat', $current_user->getPreference('datef'));
$nameValueArray['user_default_timeformat'] = self::$helperObject->get_name_value('user_default_timeformat', $current_user->getPreference('timef'));
$currencyObject = BeanFactory::newBean('Currencies');
$currencyObject->retrieve($cur_id);
$nameValueArray['user_currency_name'] = self::$helperObject->get_name_value('user_currency_name', $currencyObject->name);
$_SESSION['user_language'] = $current_language;
return array('id'=>session_id(), 'module_name'=>'Users', 'name_value_list'=>$nameValueArray);
}
LogicHook::initialize();
$GLOBALS['logic_hook']->call_custom_logic('Users', 'login_failed');
$error->set_error('invalid_login');
self::$helperObject->setFaultObject($error);
$GLOBALS['log']->info('End: SugarWebServiceImpl->login - failed login');
}
/**
* Retrieve the md5 hash of the vardef entries for a particular module.
*
* @param String $session -- Session ID returned by a previous call to login.
* @param String|array $module_name -- The name of the module to return records 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)..
* @return String The md5 hash of the vardef definition.
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_module_fields_md5($session, $module_name)
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_module_fields_md5(v3) for module: '. print_r($module_name, true));
$results = array();
if (is_array($module_name)) {
foreach ($module_name as $module) {
$results[$module] = md5(serialize(self::get_module_fields($session, $module)));
}
} else {
$results[$module_name] = md5(serialize(self::get_module_fields($session, $module_name)));
}
return $results;
}
/**
* Gets server info. This will return information like version, flavor and gmt_time.
* @return Array - flavor - String - Retrieve the specific flavor of sugar.
* - version - String - Retrieve the version number of Sugar that the server is running.
* - gmt_time - String - Return the current time on the server in the format 'Y-m-d H:i:s'. This time is in GMT.
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_server_info()
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_server_info');
global $sugar_flavor, $sugar_version, $suitecrm_version;
if (empty($sugar_version)) {
require_once('sugar_version.php');
}
if (empty($suitecrm_version)) {
include('suitecrm_version.php');
}
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_server_info');
return array('flavor' => $sugar_flavor, 'version' => $sugar_version, 'suitecrm_version' => $suitecrm_version, 'gmt_time' => TimeDate::getInstance()->nowDb());
} // fn
/**
* Retrieve the layout metadata for a given module given a specific type and view.
*
* @param String $session -- Session ID returned by a previous call to login.
* @param array $module_name(s) -- The name of the module(s) to return records 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)..
* @return array $type The type(s) of views requested. Current supported types are 'default' (for application) and 'wireless'
* @return array $view The view(s) requested. Current supported types are edit, detail, list, and subpanel.
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_module_layout($session, $a_module_names, $a_type, $a_view, $md5 = false)
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_module_layout');
global $beanList, $beanFiles;
$error = new SoapError();
$results = array();
foreach ($a_module_names as $module_name) {
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', $module_name, 'read', 'no_access', $error)) {
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_module_layout');
continue;
}
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$seed = new $class_name();
foreach ($a_view as $view) {
$aclViewCheck = (strtolower($view) == 'subpanel') ? 'DetailView' : ucfirst(strtolower($view)) . 'View';
if ($seed->ACLAccess($aclViewCheck, true)) {
foreach ($a_type as $type) {
$a_vardefs = self::$helperObject->get_module_view_defs($module_name, $type, $view);
if ($md5) {
$results[$module_name][$type][$view] = md5(serialize($a_vardefs));
} else {
$results[$module_name][$type][$view] = $a_vardefs;
}
}
}
}
}
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_module_layout');
return $results;
}
/**
* Retrieve the md5 hash of a layout metadata for a given module given a specific type and view.
*
* @param String $session -- Session ID returned by a previous call to login.
* @param array $module_name(s) -- The name of the module to return records 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)..
* @return array $type(s) The type of view requested. Current supported types are 'default' (for application) and 'wireless'
* @return array $view(s) The view requested. Current supported types are edit, detail, and list.
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_module_layout_md5($session, $module_name, $type, $view)
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_module_layout_md5');
$results = self::get_module_layout($session, $module_name, $type, $view, true);
return array('md5'=> $results);
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_module_layout_md5');
}
/**
* Retrieve the list of available modules on the system available to the currently logged in user.
*
* @param String $session -- Session ID returned by a previous call to login.
* @param String $filter -- Valid values are: all - Return all modules,
* default - Return all visible modules for the application
* mobile - Return all visible modules for the mobile view
* @return Array 'modules' -- Array - An array of module names
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_available_modules($session, $filter='all')
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_available_modules');
$error = new SoapError();
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', '', '', '', $error)) {
$error->set_error('invalid_login');
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_available_modules');
return;
} // if
$modules = array();
$availModules = array_keys($_SESSION['avail_modules']); //ACL check already performed.
switch ($filter) {
case 'default':
$modules = self::$helperObject->get_visible_modules($availModules);
break;
case 'all':
default:
$modules = $availModules;
}
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_available_modules');
return array('modules'=> $modules);
} // fn
/**
* Retrieve a list of recently viewed records by module.
*
* @param String $session -- Session ID returned by a previous call to login.
* @param String $modules -- An array of modules or 'Home' to indicate all.
* @return Array The recently viewed records
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_last_viewed($session, $module_names)
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_last_viewed');
$error = new SoapError();
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', '', '', '', $error)) {
$error->set_error('invalid_login');
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_last_viewed');
return;
} // if
$results = array();
foreach ($module_names as $module) {
if (!self::$helperObject->check_modules_access($GLOBALS['current_user'], $module, 'read')) {
$GLOBALS['log']->debug("SugarWebServiceImpl->get_last_viewed: NO ACCESS to $module");
continue;
}
if ($module == 'Home') {
$module = '';
}
$tracker = BeanFactory::newBean('Trackers');
$entryList = $tracker->get_recently_viewed($GLOBALS['current_user']->id, $module);
foreach ($entryList as $entry) {
$results[] = $entry;
}
}
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_last_viewed');
return $results;
}
/**
* Retrieve a list of upcoming activities including Calls, Meetings,Tasks and Opportunities
*
* @param String $session -- Session ID returned by a previous call to login.
* @return Array List of upcoming activities
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_upcoming_activities($session)
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_upcoming_activities');
$error = new SoapError();
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', '', '', '', $error)) {
$error->set_error('invalid_login');
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_upcoming_activities');
return;
} // if
$results = self::$helperObject->get_upcoming_activities();
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_upcoming_activities');
return $results;
}
/**
* Given a list of modules to search and a search string, return the id, module_name, along with the fields
* We will support Accounts, Bugs, Cases, Contacts, Leads, Opportunities, Project, ProjectTask, Quotes
*
* @param string $session - Session ID returned by a previous call to login.
* @param string $search_string - string to search
* @param string[] $modules - array of modules to query
* @param int $offset - a specified offset in the query
* @param int $max_results - max number of records to return
* @param string $assigned_user_id - a user id to filter all records by, leave empty to exclude the filter
* @param string[] $select_fields - An array of fields to return. If empty the default return fields will be from the active list view defs.
* @return Array return_search_result - Array('Accounts' => array(array('name' => 'first_name', 'value' => 'John', 'name' => 'last_name', 'value' => 'Do')))
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function search_by_module($session, $search_string, $modules, $offset, $max_results, $assigned_user_id = '', $select_fields = array())
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->search_by_module');
global $beanList, $beanFiles;
global $sugar_config,$current_language;
$error = new SoapError();
$output_list = array();
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', '', '', '', $error)) {
$error->set_error('invalid_login');
$GLOBALS['log']->info('End: SugarWebServiceImpl->search_by_module');
return;
}
global $current_user;
if ($max_results > 0) {
$sugar_config['list_max_entries_per_page'] = $max_results;
}
require_once('modules/Home/UnifiedSearchAdvanced.php');
require_once 'include/utils.php';
$usa = new UnifiedSearchAdvanced();
if (!file_exists($cachedfile = sugar_cached('modules/unified_search_modules.php'))) {
$usa->buildCache();
}
include($cachedfile);
$modules_to_search = array();
$unified_search_modules['Users'] = array('fields' => array());
$unified_search_modules['ProjectTask'] = array('fields' => array());
foreach ($unified_search_modules as $module=>$data) {
if (in_array($module, $modules)) {
$modules_to_search[$module] = $beanList[$module];
} // if
} // foreach
$GLOBALS['log']->info('SugarWebServiceImpl->search_by_module - search string = ' . $search_string);
if (!empty($search_string) && isset($search_string)) {
$search_string = trim(DBManagerFactory::getInstance()->quote(securexss(from_html(clean_string($search_string, 'UNIFIED_SEARCH')))));
foreach ($modules_to_search as $name => $beanName) {
$where_clauses_array = array();
$unifiedSearchFields = array() ;
foreach ($unified_search_modules[$name]['fields'] as $field=>$def) {
$unifiedSearchFields[$name] [ $field ] = $def ;
$unifiedSearchFields[$name] [ $field ]['value'] = $search_string;
}
require_once $beanFiles[$beanName] ;
$seed = new $beanName();
require_once 'include/SearchForm/SearchForm2.php' ;
if ($beanName == "User"
|| $beanName == "ProjectTask"
) {
if (!self::$helperObject->check_modules_access($current_user, $seed->module_dir, 'read')) {
continue;
} // if
if (!$seed->ACLAccess('ListView')) {
continue;
} // if
}
if ($beanName != "User"
&& $beanName != "ProjectTask"
) {
$searchForm = new SearchForm($seed, $name) ;
$searchForm->setup(array($name => array()), $unifiedSearchFields, '', 'saved_views' /* hack to avoid setup doing further unwanted processing */) ;
$where_clauses = $searchForm->generateSearchWhere() ;
require_once 'include/SearchForm/SearchForm2.php' ;
$searchForm = new SearchForm($seed, $name) ;
$searchForm->setup(array($name => array()), $unifiedSearchFields, '', 'saved_views' /* hack to avoid setup doing further unwanted processing */) ;
$where_clauses = $searchForm->generateSearchWhere() ;
$emailQuery = false;
$where = '';
if (count($where_clauses) > 0) {
$where = '('. implode(' ) OR ( ', $where_clauses) . ')';
}
$mod_strings = return_module_language($current_language, $seed->module_dir);
if (count($select_fields) > 0) {
$filterFields = $select_fields;
} else {
if (file_exists('custom/modules/'.$seed->module_dir.'/metadata/listviewdefs.php')) {
require_once('custom/modules/'.$seed->module_dir.'/metadata/listviewdefs.php');
} else {
require_once('modules/'.$seed->module_dir.'/metadata/listviewdefs.php');
}
$filterFields = array();
foreach ($listViewDefs[$seed->module_dir] as $colName => $param) {
if (!empty($param['default']) && $param['default'] == true) {
$filterFields[] = strtolower($colName);
}
}
if (!in_array('id', $filterFields)) {
$filterFields[] = 'id';
}
}
//Pull in any db fields used for the unified search query so the correct joins will be added
$selectOnlyQueryFields = array();
foreach ($unifiedSearchFields[$name] as $field => $def) {
if (isset($def['db_field']) && !in_array($field, $filterFields)) {
$filterFields[] = $field;
$selectOnlyQueryFields[] = $field;
}
}
//Add the assigned user filter if applicable
if (!empty($assigned_user_id) && isset($seed->field_defs['assigned_user_id'])) {
$ownerWhere = $seed->getOwnerWhere($assigned_user_id);
$where = "($where) AND $ownerWhere";
}
$ret_array = $seed->create_new_list_query('', $where, $filterFields, array(), 0, '', true, $seed, true);
if (empty($params) or !is_array($params)) {
$params = array();
}
if (!isset($params['custom_select'])) {
$params['custom_select'] = '';
}
if (!isset($params['custom_from'])) {
$params['custom_from'] = '';
}
if (!isset($params['custom_where'])) {
$params['custom_where'] = '';
}
if (!isset($params['custom_order_by'])) {
$params['custom_order_by'] = '';
}
$main_query = $ret_array['select'] . $params['custom_select'] . $ret_array['from'] . $params['custom_from'] . $ret_array['where'] . $params['custom_where'] . $ret_array['order_by'] . $params['custom_order_by'];
} else {
if ($beanName == "User") {
$filterFields = array('id', 'user_name', 'first_name', 'last_name', 'email_address');
$main_query = "select users.id, ea.email_address, users.user_name, first_name, last_name from users ";
$main_query = $main_query . " LEFT JOIN email_addr_bean_rel eabl ON eabl.bean_module = '{$seed->module_dir}'
LEFT JOIN email_addresses ea ON (ea.id = eabl.email_address_id) ";
$main_query = $main_query . "where ((users.first_name like '{$search_string}') or (users.last_name like '{$search_string}') or (users.user_name like '{$search_string}') or (ea.email_address like '{$search_string}')) and users.deleted = 0 and users.is_group = 0 and users.employee_status = 'Active'";
} // if
if ($beanName == "ProjectTask") {
$filterFields = array('id', 'name', 'project_id', 'project_name');
$main_query = "select {$seed->table_name}.project_task_id id,{$seed->table_name}.project_id, {$seed->table_name}.name, project.name project_name from {$seed->table_name} ";
$seed->add_team_security_where_clause($main_query);
$main_query .= "LEFT JOIN teams ON $seed->table_name.team_id=teams.id AND (teams.deleted=0) ";
$main_query .= "LEFT JOIN project ON $seed->table_name.project_id = project.id ";
$main_query .= "where {$seed->table_name}.name like '{$search_string}%'";
} // if
} // else
$GLOBALS['log']->info('SugarWebServiceImpl->search_by_module - query = ' . $main_query);
if ($max_results < -1) {
$result = $seed->db->query($main_query);
} else {
if ($max_results == -1) {
$limit = $sugar_config['list_max_entries_per_page'];
} else {
$limit = $max_results;
}
$result = $seed->db->limitQuery($main_query, $offset, $limit + 1);
}
$rowArray = array();
while ($row = $seed->db->fetchByAssoc($result)) {
$nameValueArray = array();
foreach ($filterFields as $field) {
if (in_array($field, $selectOnlyQueryFields)) {
continue;
}
$nameValue = array();
if (isset($row[$field])) {
$nameValueArray[$field] = self::$helperObject->get_name_value($field, $row[$field]);
} // if
} // foreach
$rowArray[] = $nameValueArray;
} // while
$output_list[] = array('name' => $name, 'records' => $rowArray);
} // foreach
$GLOBALS['log']->info('End: SugarWebServiceImpl->search_by_module');
return array('entry_list'=>$output_list);
} // if
return array('entry_list'=>$output_list);
} // fn
/**
* Retrieve a collection of beans that are related to the specified bean and optionally return relationship data for those related beans.
* So in this API you can get contacts info for an account and also return all those contact's email address or an opportunity info also.
*
* @param String $session -- Session ID returned by a previous call to login.
* @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)..
* @param String $module_id -- The ID of the bean in the specified module
* @param String $link_field_name -- The name of the lnk field to return records from. This name should be the name the relationship.
* @param String $related_module_query -- A portion of the where clause of the SQL statement to find the related items. The SQL query will already be filtered to only include the beans that are related to the specified bean.
* @param Array $related_fields - Array of related bean fields to be returned.
* @param Array $related_module_link_name_to_fields_array - For every related bean returrned, specify link fields name to fields info for that bean to be returned. For ex.'link_name_to_fields_array' => array(array('name' => 'email_addresses', 'value' => array('id', 'email_address', 'opt_out', 'primary_address'))).
* @param Number $deleted -- false if deleted records should not be include, true if deleted records should be included.
* @param String $order_by -- field to order the result sets by
* @return Array 'entry_list' -- Array - The records that were retrieved
* 'relationship_list' -- Array - The records link field data. The example is if asked about accounts contacts email address then return data would look like Array ( [0] => Array ( [name] => email_addresses [records] => Array ( [0] => Array ( [0] => Array ( [name] => id [value] => 3fb16797-8d90-0a94-ac12-490b63a6be67 ) [1] => Array ( [name] => email_address [value] => hr.kid.qa@example.com ) [2] => Array ( [name] => opt_out [value] => 0 ) [3] => Array ( [name] => primary_address [value] => 1 ) ) [1] => Array ( [0] => Array ( [name] => id [value] => 403f8da1-214b-6a88-9cef-490b63d43566 ) [1] => Array ( [name] => email_address [value] => kid.hr@example.name ) [2] => Array ( [name] => opt_out [value] => 0 ) [3] => Array ( [name] => primary_address [value] => 0 ) ) ) ) )
* @exception 'SoapFault' -- The SOAP error, if any
*/
public function get_relationships($session, $module_name, $module_id, $link_field_name, $related_module_query, $related_fields, $related_module_link_name_to_fields_array, $deleted, $order_by = '')
{
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->get_relationships');
global $beanList, $beanFiles;
$error = new SoapError();
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', $module_name, 'read', 'no_access', $error)) {
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_relationships');
return;
} // if
$class_name = $beanList[$module_name];
require_once($beanFiles[$class_name]);
$mod = new $class_name();
$mod->retrieve($module_id);
if (!self::$helperObject->checkQuery($error, $related_module_query, $order_by)) {
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_relationships');
return;
} // if
if (!self::$helperObject->checkACLAccess($mod, 'DetailView', $error, 'no_access')) {
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_relationships');
return;
} // if
$output_list = array();
$linkoutput_list = array();
// get all the related mmodules data.
$result = self::$helperObject->getRelationshipResults($mod, $link_field_name, $related_fields, $related_module_query, $order_by);
if (self::$helperObject->isLogLevelDebug()) {
$GLOBALS['log']->debug('SoapHelperWebServices->get_relationships - return data for getRelationshipResults is ' . var_export($result, true));
} // if
if ($result) {
$list = $result['rows'];
$filterFields = $result['fields_set_on_rows'];
if (count($list) > 0) {
// get the related module name and instantiate a bean for that.
$submodulename = $mod->$link_field_name->getRelatedModuleName();
$submoduleclass = $beanList[$submodulename];
require_once($beanFiles[$submoduleclass]);
$submoduletemp = new $submoduleclass();
foreach ($list as $row) {
$submoduleobject = @clone($submoduletemp);
// set all the database data to this object
foreach ($filterFields as $field) {
$submoduleobject->$field = $row[$field];
} // foreach
if (isset($row['id'])) {
$submoduleobject->id = $row['id'];
}
$output_list[] = self::$helperObject->get_return_value_for_fields($submoduleobject, $submodulename, $filterFields);
if (!empty($related_module_link_name_to_fields_array)) {
$linkoutput_list[] = self::$helperObject->get_return_value_for_link_fields($submoduleobject, $submodulename, $related_module_link_name_to_fields_array);
} // if
} // foreach
}
} // if
$GLOBALS['log']->info('End: SugarWebServiceImpl->get_relationships');
return array('entry_list'=>$output_list, 'relationship_list' => $linkoutput_list);
} // fn
}
SugarWebServiceImplv3::$helperObject = new SugarWebServiceUtilv3();