mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 01:10:42 +08:00
Squashed 'public/legacy/' changes from 52926f2943..c8ba0321c2
c8ba0321c2 Add support for PHP 8.3 9078c9fe6f SuiteCRM 7.14.7 Release e8c0cdb428 Fix Email compose not sending without system outbound f25f2793d5 Fix autocomplete not working fully on product number 899b8ce9cc Fix User Wizard Prompt f378b226ca Update install page to remove smtp settings bbbd5d60b9 Only allow external oauth to be the same type as email 5cf7a1198d Fix send test email on outbound e92314e443 Add filter on external oauth connection on system d242240a42 Add check for group type oauth on system outbound emails d2cd059f62 Prevent calling set required on detail view on OutboundEmails 55f7a544b3 Properly reset fields when changing auth type on OutboundEmails fd49ebccb2 Add from address validation to test function in OutboundEmails 0505626587 Fix SMTP OAuth in campaigns c631df323a Remove save of system outbound email on email settings 4b76c94820 Allow using group OAuth Connections in bounce emails d5a7868603 Add configurable timeout to test outbound email call 4c13b646b0 Remove mail_smtp_pass conditional display based on mail_smtpauth_req 2a3993bd52 Make OutboundEmailAccount from address and name required d2a6c3a882 Add ExternalOAuthProvider default Authorize url options 61ddfc3594 Add error display view 50b8223148 Use OAuth authentication when sending emails f692424805 Update SMTP test functionality to support OAuth 7a73365291 Update UI for configuring system email 9c4606bd81 Add support for auto-refreshing token in SMTP OAuth 8b1937e61a Minor fix in auth_type_fields_toggle.js 34fdf19497 Add support for OAuth in SugarPHPMailer 0fb6910698 Allow choosing different auth_types in OutboundEmailAccounts 6c22edadc5 Add auth_type and external_oauth_connection to OutboundEmailAccounts 2489d660f8 Fix importer progress bar uses incorrect values bfcca9027f Fix notice messages prevent importing 5f14f96325 Add option to group on Reports field function 05f997dbaa Fix #10345 - Add toggle and field js files 01547c5fdf Fix #10345 - Add redirect uri type field a5df5d3c84 Fix #10345 - Microsoft Azure OAuth Redirect URL d32908885f Add support for EntryPoint /ep extension 978d912437 Fix #10532, #10377 - Display issues in global search 5d0ae0b756 Fix #10147, #10396 - Smarty unregistered function deprecated notice 50e4f3e182 Fix #10543 - Remove Security Groups button on subpanelsbased on EditView 06341925f5 Fix #10113 - Contracts / List Items table for services has bogus width baecf4aba2 Allow End Users to use the PATCH verb for the V8 API 295ee2cec5 Fix #8632 - API V8 /meta/fields/{moduleName} endpoint output without field labels e05795f930 Fix salesagility#10616 - Default values of DateTime always in English and value “first day of next month” gives an error 6a5d6e84b9 Fix #10285 - Fix non-countable error 2894d48110 Fix #10243 - studio not saving field properties correctly 33eb278141 Fix #10624 - Prevent Multiple Submissions on Survey Forms 5e1e966b95 Fix #10606 - Recently viewed items tooltip shows module name instead of full record name c3a58cd1fb Fix - #10611 Subpanels don't show related records links when view permission is set to "group" bebc66986c Fix #8280 - Fix Autocomplete search in line items 6ae6891ddc Fix #10475 - Rename the History subpanel by changing the label a665c95d7f Fix #10264 - Smarty Error Assigned_user_name in SearchView.tpl dcf72e04dc Fix #10637 - Local users gets Profile wizard on each login 026c014055 Fix #10660 - Email Template not saving in plain text b82d9a76c6 Fix #10661 - Add check for preference before setting to default 77c50bb53f Fix #9809 - Incorrect parsing of 0 values in PDF templates 23a9953956 Fix #10400,#9823 Correctly find the id of related objects in search results 7bcd1f9dca Fix #10479 - Call LoggerManager's warn() method instead of warning() f4d44b016a Fix #10502 - Remove duplicate line afcf009a99 Fix #10549 - Variable name typo in getEmailInfo ba11f93fb4 Fix salesagility#10564 - Thank you message in Surveys only in English 75d95fed99 Fix #10599 - Update Import Error fe188ec0ee Fix #10599 - Update Import Error Styling REVERT: 52926f2943 PHP 8.3 - Throw exception on Projects Gantt Table REVERT: 7f5ad0158a PHP 8.3 - Fix PHP warning on import REVERT: 282a1e0f89 PHP 8.3 - Fix currency formatting on listview REVERT: dbed1d82cf PHP 8.3 - Fix PHP errors REVERT: 07eaa3ff60 PHP 8.3 - Fix workflow date conversion error REVERT: 13ccac1a3c PHP 8.3 - Fix Dates Error on calls REVERT: 2b92f2cb15 Fix #10264 - Error `Assigned_user_name` `SearchView.tpl` (`{php}` tag now crashes Smarty 4) REVERT: 660d546c2b Fix #10264 - Error Assigned_user_name SearchView.tpl ({php} tag now crashes Smarty 4) REVERT: ecb6a6d89b PHP 8.3 - Fix report value not showing REVERT: fece2fd35e PHP 8.3 - Fix PDF templates breaking detail view REVERT: e9550a99a1 PHP 8.3 - Set same default as imap called function REVERT: 17bde6e5a0 PHP 8.3 - Add default to cookie on susoap REVERT: 01768fc962 PHP 8.3 - Remove deprecated param setting REVERT: f3f62431fa PHP 8.3 - Remove deprecated ini setting REVERT: 721fa93977 PHP 8.3 - Fix readability of if REVERT: f9f7352a1a PHP 8.3 - Fix pdf template breaking listview REVERT: 8bffb4d83a PHP 8.3 - Update null to -1 on preg split REVERT: db663af17c PHP 8.3 - Remove unused time field on calls date start REVERT: 32b6a6289b PHP 8.3 - don't show project task table if no tasks REVERT: 04257e7663 PHP 8.3 - Fix Reports merge error REVERT: 514319c6c9 PHP 8.3 - Add entry point variable to controller REVERT: f37e6af3fb PHP 8.3 - Add quotes to array keys REVERT: 955a6f8790 PHP 8.3 - Update deprecated use of self REVERT: b81b1247ec PHP 8.3 - Fix invitee id on reminder REVERT: 18375148b9 PHP 8.3 - Update OAuth searchdefs REVERT: f5fdda17f5 PHP 8.3 - Fix margin reading as empty string REVERT: ad144cb20a PHP 8.3 - Update function variable types REVERT: f174ae27a8 PHP 8.3 - Update deprecated filter variable REVERT: 29eb104ec5 PHP 8.3 - Update deprecated date functions REVERT: 41ed417a94 PHP 8.3 - Update checks to not pass null REVERT: 48169c4768 PHP 8.3 - Update Missing Labels REVERT: b62e4a3d17 PHP 8.3 - Fix dashlet warnings and deprecations REVERT: 5e745b6491 PHP 8.3 - Add and update variables on ListView REVERT: b7dee66ccf PHP 8.3 - Update labels on tpl REVERT: 2630420e9b PHP 8.3 - Add checks and defaults for editview field tpls REVERT: 85aa7efd57 PHP 8.3 - Add checks for detailview field tpls REVERT: 59d90f871e PHP 8.3 - Add extra checks on recurring message tpls REVERT: 90fab9c2ac PHP 8.3 - Fix Duplicate variable init git-subtree-dir: public/legacy git-subtree-split: c8ba0321c2d89d66ed3c3a4ab175ef8cd590be84
This commit is contained in:
parent
8d824c79af
commit
989e304671
122 changed files with 3152 additions and 2017 deletions
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// Swagger needs this, but should remove - CORS
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
|
||||
header('Access-Control-Allow-Methods: POST, PATCH, GET, OPTIONS, PUT, DELETE');
|
||||
header('Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With');
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
|
|
|
@ -76,8 +76,9 @@ class MetaService
|
|||
'default',
|
||||
'len',
|
||||
'precision',
|
||||
'comments',
|
||||
'comment',
|
||||
'required',
|
||||
'vname'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,7 +90,7 @@ class UserPreferencesService
|
|||
$preferences = [];
|
||||
while ($row = $db->fetchByAssoc($result)) {
|
||||
$category = $row['category'];
|
||||
$preferences[$category] = unserialize(base64_decode($row['contents']));
|
||||
$preferences[$category] = unserialize(base64_decode($row['contents']), ['allowed_classes' => false]);
|
||||
}
|
||||
|
||||
$dataResponse = new DataResponse('UserPreference', $params->getUserId());
|
||||
|
|
|
@ -916,7 +916,7 @@ class PackageManager
|
|||
$installed->manifest = base64_encode(serialize($serial_manifest));
|
||||
$installed->save();
|
||||
} else {
|
||||
$serial_manifest = unserialize(base64_decode($installed->manifest));
|
||||
$serial_manifest = unserialize(base64_decode($installed->manifest), ['allowed_classes' => false]);
|
||||
$manifest = $serial_manifest['manifest'];
|
||||
}
|
||||
if (($upgrades_installed==0 || $uh->UninstallAvailable($installeds, $installed))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<img width="180px" height="41px" src="https://suitecrm.com/wp-content/uploads/2017/12/logo.png" align="right" />
|
||||
</a>
|
||||
|
||||
# SuiteCRM 7.14.6
|
||||
# SuiteCRM 7.14.7
|
||||
|
||||
[](https://travis-ci.org/salesagility/SuiteCRM)
|
||||
[](https://codecov.io/gh/salesagility/SuiteCRM/branch/hotfix)
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
{
|
||||
"name": "salesagility/suitecrm",
|
||||
"name": "suitecrm/suitecrm",
|
||||
"description": "SuiteCRM",
|
||||
"homepage": "https://suitecrm.com",
|
||||
"type": "project",
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "SalesAgility Ltd"
|
||||
"name": "SuiteCRM Ltd"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/salesagility/SuiteCRM/issues",
|
||||
"issues": "https://github.com/suitecrm/SuiteCRM/issues",
|
||||
"wiki": "https://docs.suitecrm.com",
|
||||
"forum": "https://community.suitecrm.com",
|
||||
"chat": "https://gitter.im/suitecrm/Lobby",
|
||||
"source": "https://github.com/salesagility/SuiteCRM"
|
||||
"source": "https://github.com/suitecrm/SuiteCRM"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "vendor",
|
||||
|
@ -39,10 +38,11 @@
|
|||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-intl": "*",
|
||||
"consolidation/robo": "^3.0",
|
||||
"elasticsearch/elasticsearch": "^7.13",
|
||||
"ezyang/htmlpurifier": "^4.10",
|
||||
"google/apiclient": "^2.7",
|
||||
"google/apiclient": "^2.14",
|
||||
"google/recaptcha": "^1.1",
|
||||
"gymadarasz/ace": "^1.2",
|
||||
"gymadarasz/imagesloaded": "^4.1",
|
||||
|
@ -60,13 +60,12 @@
|
|||
"slim/slim": "^3.8",
|
||||
"smarty/smarty": "^4",
|
||||
"soundasleep/html2text": "~0.5",
|
||||
"symfony/options-resolver": "^3.4",
|
||||
"symfony/validator": "^3.4",
|
||||
"symfony/options-resolver": "^5.4",
|
||||
"symfony/validator": "^5.4",
|
||||
"symfony/yaml": "^5.2",
|
||||
"tecnickcom/tcpdf": "^6.4",
|
||||
"tedivm/jshrink": "^1.3",
|
||||
"tinymce/tinymce": "^5.10",
|
||||
"vlucas/phpdotenv": "^3.5",
|
||||
"voku/anti-xss": "^4.0",
|
||||
"wikimedia/composer-merge-plugin": "^2.0",
|
||||
"zbateson/mail-mime-parser": "^2.2",
|
||||
|
@ -74,8 +73,7 @@
|
|||
"zf1/zend-loader": "^1.12",
|
||||
"zf1/zend-oauth": "^1.12",
|
||||
"zf1/zend-registry": "^1.12",
|
||||
"zf1/zend-search-lucene": "^1.12",
|
||||
"ext-intl": "*"
|
||||
"zf1/zend-search-lucene": "^1.12"
|
||||
},
|
||||
"require-dev": {
|
||||
"browserstack/browserstack-local": "^1.1",
|
||||
|
@ -95,7 +93,8 @@
|
|||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rector/rector": "^0.16.0",
|
||||
"scssphp/scssphp": "^1.5"
|
||||
"scssphp/scssphp": "^1.5",
|
||||
"vlucas/phpdotenv": "^5.5"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
|
|
2425
composer.lock
generated
2425
composer.lock
generated
File diff suppressed because it is too large
Load diff
4
cron.php
4
cron.php
|
@ -57,7 +57,7 @@ if (!is_windows()) {
|
|||
$cronUser = getRunningUser();
|
||||
|
||||
if ($cronUser == '') {
|
||||
$GLOBALS['log']->warning('cron.php: can\'t determine running user. No cron user checks will occur.');
|
||||
$GLOBALS['log']->warn('cron.php: can\'t determine running user. No cron user checks will occur.');
|
||||
} elseif (array_key_exists('cron', $sugar_config) && array_key_exists('allowed_cron_users', $sugar_config['cron'])) {
|
||||
if (!in_array($cronUser, $sugar_config['cron']['allowed_cron_users'])) {
|
||||
$GLOBALS['log']->fatal("cron.php: running as $cronUser is not allowed in allowed_cron_users ".
|
||||
|
@ -70,7 +70,7 @@ if (!is_windows()) {
|
|||
sugar_die('cron.php running with user that is not in allowed_cron_users in config.php');
|
||||
}
|
||||
} else {
|
||||
$GLOBALS['log']->warning('cron.php: missing expected allowed_cron_users entry in config.php. ' .
|
||||
$GLOBALS['log']->warn('cron.php: missing expected allowed_cron_users entry in config.php. ' .
|
||||
'No cron user checks will occur.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1012,7 +1012,11 @@ class SugarController
|
|||
require_once($this->entry_point_registry[$entryPoint]['file']);
|
||||
$this->_processed = true;
|
||||
$this->view = '';
|
||||
} else {
|
||||
$this->no_action();
|
||||
}
|
||||
} elseif (isset($_REQUEST['entryPoint'])) {
|
||||
$this->no_action();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ $action_view_map['modulelistmenu']= 'modulelistmenu';
|
|||
$action_view_map['favorites']= 'favorites';
|
||||
$action_view_map['ajaxui']= 'ajaxui';
|
||||
$action_view_map['noaccess']= 'noaccess';
|
||||
$action_view_map['errors']= 'errors';
|
||||
|
||||
// SugarPDF
|
||||
$action_view_map['sugarpdf']= 'sugarpdf';
|
||||
|
|
|
@ -558,7 +558,7 @@ class SugarApplication
|
|||
if ($dieIfInvalid) {
|
||||
header("Cache-Control: no-cache, must-revalidate");
|
||||
$ss = new Sugar_Smarty;
|
||||
$ss->assign('host', $http_host[0]);
|
||||
$ss->assign('host', securexss($http_host[0]));
|
||||
$ss->assign('action', $this->controller->action);
|
||||
$ss->assign('whiteListString', $whiteListString);
|
||||
$ss->display('include/MVC/View/tpls/xsrf.tpl');
|
||||
|
@ -577,7 +577,7 @@ class SugarApplication
|
|||
$whiteListString = "'" . implode("', '", $whiteListActions) . "'";
|
||||
|
||||
$ss = new Sugar_Smarty;
|
||||
$ss->assign('host', $http_ref['host']);
|
||||
$ss->assign('host', securexss($http_ref['host']));
|
||||
$ss->assign('action', $this->controller->action);
|
||||
$ss->assign('whiteListString', $whiteListString);
|
||||
$ss->display('include/MVC/View/tpls/xsrf.tpl');
|
||||
|
|
39
include/MVC/View/views/view.errors.php
Normal file
39
include/MVC/View/views/view.errors.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM 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 SUITECRM, SUITECRM 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/>.
|
||||
*
|
||||
* 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
|
||||
* "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 "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
|
||||
class ViewErrors extends SugarView
|
||||
{
|
||||
public $type = 'errors';
|
||||
|
||||
/**
|
||||
* @see SugarView::display()
|
||||
*/
|
||||
public function display()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -89,6 +89,8 @@ class OutboundEmail
|
|||
public $mail_smtpssl; // bool
|
||||
public $mail_smtpdisplay; // calculated value, not in DB
|
||||
public $new_with_id = false;
|
||||
public $auth_type; // no_auth, oauth2, external_oauth
|
||||
public $external_oauth_connection_id; // no_auth, oauth2, external_oauth
|
||||
|
||||
/**
|
||||
* Sole constructor
|
||||
|
@ -389,6 +391,19 @@ class OutboundEmail
|
|||
return $allowAccess;
|
||||
}
|
||||
|
||||
public function getSystemEmail(): ?object
|
||||
{
|
||||
$q = "SELECT id FROM outbound_email WHERE type = 'system' AND deleted = 0";
|
||||
$r = $this->db->query($q);
|
||||
$a = $this->db->fetchByAssoc($r);
|
||||
|
||||
if (!empty($a)) {
|
||||
return $this->retrieve($a['id']) ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the system's Outbound options
|
||||
*/
|
||||
|
|
|
@ -186,7 +186,7 @@ class SearchForm
|
|||
$this->th->ss->assign('action', $this->action);
|
||||
$this->th->ss->assign('displayView', $this->displayView);
|
||||
$this->th->ss->assign('viewTab', $this->getViewTab());
|
||||
$this->th->ss->assign('user_options', get_user_array(false)); // Fix https://github.com/salesagility/SuiteCRM/issues/10264
|
||||
$this->th->ss->assign('user_options', get_user_array(false));
|
||||
|
||||
require_once('modules/MySettings/StoreQuery.php');
|
||||
$storeQuery = new StoreQuery();
|
||||
|
|
|
@ -863,8 +863,6 @@ class SubPanelDefinitions
|
|||
*/
|
||||
public function get_hidden_subpanels()
|
||||
{
|
||||
global $moduleList;
|
||||
|
||||
//create variable as static to minimize queries
|
||||
static $hidden_subpanels = null;
|
||||
|
||||
|
@ -879,25 +877,9 @@ class SubPanelDefinitions
|
|||
$hidden_subpanels = $administration->settings['MySettings_hide_subpanels'];
|
||||
$hidden_subpanels = trim($hidden_subpanels);
|
||||
|
||||
//make sure serialized string is not empty
|
||||
if (!empty($hidden_subpanels)) {
|
||||
//decode and unserialize to retrieve the array
|
||||
$hidden_subpanels = base64_decode($hidden_subpanels);
|
||||
$hidden_subpanels = unserialize($hidden_subpanels);
|
||||
|
||||
//Ensure modules saved in the preferences exist.
|
||||
//get user preference
|
||||
//unserialize and add to array if not empty
|
||||
$pref_hidden = array();
|
||||
foreach ($pref_hidden as $id => $pref_hidden_panel) {
|
||||
$hidden_subpanels[] = $pref_hidden_panel;
|
||||
}
|
||||
} else {
|
||||
//no settings found, return empty
|
||||
return $hidden_subpanels;
|
||||
$hidden_subpanels = unserialize(base64_decode($hidden_subpanels), ['allowed_classes' => false]);
|
||||
}
|
||||
} else { //no settings found, return empty
|
||||
return $hidden_subpanels;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ class SugarCacheFile extends SugarCacheAbstract
|
|||
) {
|
||||
// load up the external cache file
|
||||
if (is_file($cachedfile = sugar_cached($this->_cacheFileName))) {
|
||||
$this->localCache = unserialize(file_get_contents($cachedfile));
|
||||
$this->localCache = unserialize(file_get_contents($cachedfile), ['allowed_classes' => false]);
|
||||
}
|
||||
|
||||
if (isset($this->_localStore[$key])) {
|
||||
|
|
|
@ -141,7 +141,7 @@ class SugarCacheRedis extends SugarCacheAbstract
|
|||
}
|
||||
|
||||
return is_string($returnValue) ?
|
||||
unserialize($returnValue) :
|
||||
unserialize($returnValue, ['allowed_classes' => false]) :
|
||||
$returnValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class SugarCacheZend extends SugarCacheAbstract
|
|||
return null;
|
||||
}
|
||||
return is_string($raw_cache_value) ?
|
||||
unserialize($raw_cache_value) :
|
||||
unserialize($raw_cache_value, ['allowed_classes' => false]) :
|
||||
$raw_cache_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,5 +40,4 @@
|
|||
|
||||
*}
|
||||
{{capture name=display_size assign=size}}{{$displayParams.size|default:6}}{{/capture}}
|
||||
|
||||
{html_options name='{{$vardef.name}}[]' options=$user_options size="{{$size}}" style="width: 150px" {{if $size > 1}}multiple="1"{{/if}} selected={{sugarvar key='value' string=true}}}
|
||||
|
|
|
@ -132,23 +132,28 @@ class SugarPHPMailer extends PHPMailer
|
|||
$this->Mailer = 'smtp';
|
||||
$this->Host = $oe->mail_smtpserver;
|
||||
$this->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$this->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$this->SMTPSecure = 'tls';
|
||||
} // if
|
||||
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $oe->mail_smtpuser;
|
||||
$this->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$this->setSecureProtocol($oe->mail_smtpssl);
|
||||
$this->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$this->Mailer = 'sendmail';
|
||||
}
|
||||
}
|
||||
|
||||
public function setSystemFromAddress(): void
|
||||
{
|
||||
require_once 'include/OutboundEmail/OutboundEmail.php';
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemMailerSettings();
|
||||
|
||||
$this->From = $oe->smtp_from_addr ?? '';
|
||||
$this->FromName = $oe->smtp_from_name ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefills mailer for system
|
||||
*/
|
||||
|
@ -166,22 +171,81 @@ class SugarPHPMailer extends PHPMailer
|
|||
$this->Mailer = 'smtp';
|
||||
$this->Host = $oe->mail_smtpserver;
|
||||
$this->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$this->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$this->SMTPSecure = 'tls';
|
||||
} // if
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $oe->mail_smtpuser;
|
||||
$this->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$this->setSecureProtocol($oe->mail_smtpssl);
|
||||
$this->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$this->Mailer = 'sendmail';
|
||||
}
|
||||
}
|
||||
|
||||
public function initSMTPAuth(
|
||||
string $authType,
|
||||
string $externalOAuthConnectionId,
|
||||
string $smtpUser,
|
||||
string $smtpPass,
|
||||
): void {
|
||||
|
||||
if ($authType === 'oauth') {
|
||||
$this->initOAuth(
|
||||
$authType,
|
||||
$externalOAuthConnectionId,
|
||||
$smtpUser,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($authType === 'basic') {
|
||||
$this->SMTPAuth = true;
|
||||
$this->Username = $smtpUser;
|
||||
$this->Password = $smtpPass;
|
||||
}
|
||||
}
|
||||
|
||||
public function initOAuth(
|
||||
string $authType,
|
||||
string $externalOAuthConnectionId,
|
||||
string $smtpUser
|
||||
): void
|
||||
{
|
||||
if ($authType !== 'oauth') {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->isSMTP();
|
||||
$this->SMTPAuth = true;
|
||||
|
||||
$this->AuthType = 'XOAUTH2';
|
||||
|
||||
$oAuthConnectionId = $externalOAuthConnectionId;
|
||||
|
||||
require_once 'modules/ExternalOAuthConnection/services/OAuthAuthorizationService.php';
|
||||
$oAuth = new OAuthAuthorizationService();
|
||||
|
||||
$oAuth->refreshExpiredOAuthToken($oAuthConnectionId);
|
||||
|
||||
/** @var ExternalOAuthConnection $oauthConnection */
|
||||
$oauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $oAuthConnectionId);
|
||||
$providerId = $oauthConnection->external_oauth_provider_id;
|
||||
|
||||
$oauthConfig = new \PHPMailer\PHPMailer\OAuth([
|
||||
'provider' => $oAuth?->getProvider($providerId)?->getProvider($oauthConnection->client_id, $oauthConnection->client_secret),
|
||||
'clientId' => $oauthConnection->client_id,
|
||||
'refreshToken' => $oauthConnection->refresh_token,
|
||||
'clientSecret' => $oauthConnection->client_secret,
|
||||
'userName' => $smtpUser
|
||||
]);
|
||||
|
||||
$this->setOAuth(
|
||||
$oauthConfig
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* handles Charset translation for all visual parts of the email.
|
||||
*/
|
||||
|
@ -469,7 +533,7 @@ eoq;
|
|||
$ret = parent::send();
|
||||
$this->exceptions = $saveExceptionsState;
|
||||
} catch (Exception $e) {
|
||||
$phpMailerExceptionMsg=$e->errorMessage(); //Pretty error messages from PHPMailer
|
||||
$phpMailerExceptionMsg =$e->getMessage(); //Pretty error messages from PHPMailer
|
||||
if ($phpMailerExceptionMsg) {
|
||||
$GLOBALS['log']->error("send: PHPMailer Exception: { $phpMailerExceptionMsg }");
|
||||
}
|
||||
|
@ -490,4 +554,18 @@ eoq;
|
|||
*/
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function setSecureProtocol($smtpSsl): void
|
||||
{
|
||||
$this->protocol = ($smtpSsl) ? "ssl://" : "tcp://";
|
||||
if ($smtpSsl == 1) {
|
||||
$this->protocol = "ssl://";
|
||||
$this->SMTPSecure = 'ssl';
|
||||
}
|
||||
if ($smtpSsl == 2) {
|
||||
$this->protocol = "ssl://";
|
||||
$this->SMTPSecure = 'tls';
|
||||
}
|
||||
}
|
||||
|
||||
} // end class definition
|
||||
|
|
|
@ -341,7 +341,7 @@ class SugarTheme
|
|||
}
|
||||
if (!inDeveloperMode()) {
|
||||
if (is_file($cachedfile = sugar_cached($this->getFilePath().'/pathCache.php'))) {
|
||||
$caches = unserialize(file_get_contents($cachedfile));
|
||||
$caches = unserialize(file_get_contents($cachedfile), ['allowed_classes' => false]);
|
||||
if (isset($caches['jsCache'])) {
|
||||
$this->_jsCache = $caches['jsCache'];
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ class SugarTheme
|
|||
}
|
||||
$cachedfile = sugar_cached($this->getFilePath().'/spriteCache.php');
|
||||
if (!empty($GLOBALS['sugar_config']['use_sprites']) && is_file($cachedfile)) {
|
||||
$this->_spriteCache = unserialize(sugar_file_get_contents($cachedfile));
|
||||
$this->_spriteCache = unserialize(sugar_file_get_contents($cachedfile), ['allowed_classes' => false]);
|
||||
}
|
||||
}
|
||||
$this->_initialCacheSize = array(
|
||||
|
|
|
@ -75,12 +75,25 @@ class Sugar_Smarty extends Smarty
|
|||
mkdir_recursive(SUGAR_SMARTY_DIR . 'cache', true);
|
||||
}
|
||||
|
||||
$this->template_dir = '.';
|
||||
$this->compile_dir = SUGAR_SMARTY_DIR . 'templates_c';
|
||||
$this->config_dir = SUGAR_SMARTY_DIR . 'configs';
|
||||
$this->cache_dir = SUGAR_SMARTY_DIR . 'cache';
|
||||
//$this->request_use_auto_globals = true; // to disable Smarty from using long arrays
|
||||
$this->setTemplateDir('.');
|
||||
$this->setCompileDir(SUGAR_SMARTY_DIR . 'templates_c');
|
||||
$this->setCacheDir(SUGAR_SMARTY_DIR . 'cache');
|
||||
$this->setConfigDir(SUGAR_SMARTY_DIR . 'configs');
|
||||
|
||||
$this->registerPHPFunctions([
|
||||
'count',
|
||||
'intval',
|
||||
'is_string',
|
||||
'key',
|
||||
'preg_match',
|
||||
'substr',
|
||||
'strpos',
|
||||
'strstr',
|
||||
'strtoupper',
|
||||
'strval',
|
||||
'url2html'
|
||||
]);
|
||||
|
||||
//TODO fix literals
|
||||
$this->auto_literal = false;
|
||||
|
||||
|
@ -94,7 +107,16 @@ class Sugar_Smarty extends Smarty
|
|||
$this->assign("VERSION_MARK", getVersionedPath(''));
|
||||
}
|
||||
|
||||
|
||||
public function registerPHPFunctions(array $functions): void
|
||||
{
|
||||
foreach ($functions as $function) {
|
||||
try {
|
||||
$this->registerPlugin(Smarty::PLUGIN_MODIFIER, $function, $function);
|
||||
} catch (SmartyException $e) {
|
||||
$GLOBALS['log']->fatal('Smarty: Failed to register PHP function' . $function . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default _unlink method call to fix Bug 53010
|
||||
|
|
|
@ -125,10 +125,11 @@ class SugarWidgetSubPanelDetailViewLink extends SugarWidgetField
|
|||
$detailView = $layout_def['DetailView'] ?? '';
|
||||
$ownerId = $layout_def['owner_id'] ?? '';
|
||||
$ownerModule = $layout_def['owner_module'] ?? '';
|
||||
$groupAccessView = SecurityGroup::groupHasAccess($module,$record,'view');
|
||||
if (!empty($record) &&
|
||||
($detailView && !$layout_def['owner_module']
|
||||
|| $detailView && !ACLController::moduleSupportsACL($layout_def['owner_module'])
|
||||
|| ACLController::checkAccess($ownerModule, 'view', $ownerId == $current_user->id))) {
|
||||
|| $detailView && !ACLController::moduleSupportsACL($layout_def['owner_module'])
|
||||
|| ACLController::checkAccess($ownerModule, 'view', $ownerId == $current_user->id, 'module', $groupAccessView))) {
|
||||
$link = ajaxLink("index.php?module=$module&action=$action&record={$record}{$parent}");
|
||||
if ($module == 'EAPM') {
|
||||
$link = "index.php?module=$module&action=$action&record={$record}{$parent}";
|
||||
|
|
|
@ -115,8 +115,7 @@ class SugarWidgetSubPanelRemoveButton extends SugarWidgetField
|
|||
$hideremove = true;
|
||||
}
|
||||
|
||||
//based on listview since that lets you select records
|
||||
if ($layout_def['ListView'] && !$hideremove) {
|
||||
if ($layout_def['EditView'] && !$hideremove) {
|
||||
$retStr = "<a href=\"javascript:sub_p_rem('$subpanel', '$linked_field'"
|
||||
. ", '$record', $refresh_page);\""
|
||||
. ' class="listViewTdToolsS1"'
|
||||
|
|
|
@ -296,6 +296,12 @@ $app_list_strings = array(
|
|||
'Dr.' => 'Dr.',
|
||||
'Prof.' => 'Prof.',
|
||||
),
|
||||
|
||||
'redirect_uri_type_dom' => [
|
||||
'pretty_url' => 'Pretty URL (/ep/)',
|
||||
'query_string' => 'Query String (index.php?entryPoint=)'
|
||||
],
|
||||
|
||||
//time is in seconds; the greater the time the longer it takes;
|
||||
'reminder_max_time' => 90000,
|
||||
'reminder_time_options' => array(
|
||||
|
@ -711,6 +717,12 @@ $app_list_strings = array(
|
|||
'oauth' => 'OAuth',
|
||||
],
|
||||
|
||||
'dom_outbound_email_auth_types' => [
|
||||
'no_auth' => 'No Auth',
|
||||
'basic' => 'Basic Auth',
|
||||
'oauth' => 'OAuth',
|
||||
],
|
||||
|
||||
'dom_external_oauth_connection_types' => [
|
||||
'personal' => 'Personal',
|
||||
'group' => 'Group',
|
||||
|
@ -1399,6 +1411,7 @@ $app_strings = array(
|
|||
'LBL_EMAIL_SETTINGS_CHECK_INTERVAL' => 'Check for New Mail',
|
||||
'LBL_EMAIL_SETTINGS_FROM_ADDR' => 'From Address',
|
||||
'LBL_EMAIL_SETTINGS_FROM_TO_EMAIL_ADDR' => 'Email Address For Test Notification:',
|
||||
'LBL_EMAIL_SETTINGS_FROM_ADDR_NOT_SET' => 'From address and/or From name not set',
|
||||
'LBL_EMAIL_SETTINGS_FROM_NAME' => 'From Name',
|
||||
'LBL_EMAIL_SETTINGS_REPLY_TO_ADDR' => 'Reply to Address',
|
||||
'LBL_EMAIL_SETTINGS_FULL_SYNC' => 'Synchronize All Mail Accounts',
|
||||
|
@ -3950,6 +3963,8 @@ $app_strings['LBL_VALUE_SET_PLACEHOLDER'] = 'Value set. Enter new value to overr
|
|||
$app_strings['ERR_IMAP_OAUTH_CONNECTION_ERROR'] = 'Not able to connect using OAuth login with Inbound Email server. For connection: ';
|
||||
$app_strings['WARN_OAUTH_TOKEN_SESSION_EXPIRED'] = 'Your IMAP OAuth session has expired, please login again in the connection: ';
|
||||
|
||||
$app_strings['ERR_OAUTH_CONNECTION_ERROR'] = 'Not able to connect using OAuth login. For connection: ';
|
||||
|
||||
$app_strings['LBL_KEY'] = 'Key';
|
||||
$app_strings['LBL_VALUE'] = 'Value';
|
||||
$app_strings['LBL_OPTIONAL'] = 'Optional';
|
||||
|
|
|
@ -154,7 +154,7 @@ class nusoap_wsdlcache
|
|||
$this->debug("$wsdl ($filename) not in cache (2)");
|
||||
}
|
||||
$this->releaseMutex($filename);
|
||||
return (!is_null($s)) ? unserialize($s) : null;
|
||||
return (!is_null($s)) ? unserialize($s, ['allowed_classes' => false]) : null;
|
||||
}
|
||||
$this->debug("Unable to obtain mutex for $filename in get");
|
||||
|
||||
|
|
|
@ -2393,7 +2393,7 @@ function clean_xss($str, $cleanImg = true)
|
|||
$sugar_config['email_xss'] = getDefaultXssTags();
|
||||
}
|
||||
|
||||
$xsstags = unserialize(base64_decode($sugar_config['email_xss']));
|
||||
$xsstags = unserialize(base64_decode($sugar_config['email_xss']), ['allowed_classes' => false]);
|
||||
|
||||
// cn: bug 13079 - "on\w" matched too many non-events (cONTact, strONG, etc.)
|
||||
$jsEvents = 'onblur|onfocus|oncontextmenu|onresize|onscroll|onunload|ondblclick|onclick|';
|
||||
|
@ -5978,7 +5978,7 @@ function sugar_unserialize($value)
|
|||
return false;
|
||||
}
|
||||
|
||||
return unserialize($value);
|
||||
return unserialize($value, ['allowed_classes' => false]);
|
||||
}
|
||||
|
||||
define('DEFAULT_UTIL_SUITE_ENCODING', 'UTF-8');
|
||||
|
|
|
@ -589,343 +589,6 @@ EOQ;
|
|||
|
||||
//--End of scenarios
|
||||
|
||||
//---------------
|
||||
// SMTP Settings
|
||||
//-------------------->
|
||||
|
||||
// smtp
|
||||
// TODO-t: test it for all types
|
||||
$MAIL_SSL_OPTIONS_GMAIL = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], '2');
|
||||
//$MAIL_SSL_OPTIONS_YAHOO = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], '1');
|
||||
$MAIL_SSL_OPTIONS_EXCHG = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], 'none');
|
||||
$MAIL_SSL_OPTIONS_OTHER = get_select_options_with_id($app_list_strings['email_settings_for_ssl'], 'none');
|
||||
|
||||
// set default notify_allow_default_outbound checkbox value
|
||||
$notify_allow_default_outbound_checked = empty($_SESSION['notify_allow_default_outbound']) ? '' : ' checked="checked" ';
|
||||
|
||||
// set default smtp toggle buttons selected value
|
||||
if (empty($_SESSION['smtp_tab_selected'])) {
|
||||
$_SESSION['smtp_tab_selected'] = 'smtp_tab_other';
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['smtp_from_name']) || !$_SESSION['smtp_from_name']) {
|
||||
$_SESSION['smtp_from_name'] = 'SuiteCRM';
|
||||
}
|
||||
if (!isset($_SESSION['smtp_from_addr']) || !$_SESSION['smtp_from_addr']) {
|
||||
$_SESSION['smtp_from_addr'] = 'do_not_reply@example.com';
|
||||
}
|
||||
|
||||
$out .= <<<EOQ
|
||||
<div class="floatbox full" id="fb2">
|
||||
<!-- smtp settings -->
|
||||
<h3 onclick="$(this).next().toggle();" class="toggler">» {$mod_strings['LBL_MAIL_SMTP_SETTINGS']}</h3>
|
||||
<div style="display: none;">
|
||||
|
||||
<br>
|
||||
<!--
|
||||
<p>{$mod_strings['LBL_WIZARD_SMTP_DESC']}</p>
|
||||
-->
|
||||
|
||||
<!-- smtp types toggler buttons -->
|
||||
|
||||
<p style="display: inline;">
|
||||
|
||||
<div>
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_FROM_NAME']}</label>
|
||||
<input type="text" name="smtp_from_name" value="{$_SESSION['smtp_from_name']}">
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_FROM_ADDR']}</label>
|
||||
<input type="email" name="smtp_from_addr" value="{$_SESSION['smtp_from_addr']}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
|
||||
{$mod_strings['LBL_CHOOSE_EMAIL_PROVIDER']} </p><div class="tooltip-toggle"> <em>i</em> <div class="tooltip">{$mod_strings['LBL_WIZARD_SMTP_DESC']}</div></div>
|
||||
<div class="clear"></div>
|
||||
<div>
|
||||
<input type="button" class="smtp_tab_toggler" id="smtp_tab_gmail_toggler" for="smtp_tab_gmail" value="{$mod_strings['LBL_SMTPTYPE_GMAIL']}" />
|
||||
<input type="button" class="smtp_tab_toggler" id="smtp_tab_yahoo_toggler" for="smtp_tab_yahoo" value="{$mod_strings['LBL_SMTPTYPE_YAHOO']}" />
|
||||
<input type="button" class="smtp_tab_toggler" id="smtp_tab_exchange_toggler" for="smtp_tab_exchange" value="{$mod_strings['LBL_SMTPTYPE_EXCHANGE']}" />
|
||||
<input type="button" class="smtp_tab_toggler selected" id="smtp_tab_other_toggler" for="smtp_tab_other" value="{$mod_strings['LBL_SMTPTYPE_OTHER']}" />
|
||||
<input type="hidden" name="smtp_tab_selected" value="{$_SESSION['smtp_tab_selected']}">
|
||||
</div>
|
||||
<!-- smtp / gmail tab -->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_gmail">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPSERVER']}</label>
|
||||
<input type="text" name="smtp_tab_gmail[mail_smtpserver]" size="25" maxlength="255" value="smtp.gmail.com">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPPORT']}</label>
|
||||
<input type="text" name="smtp_tab_gmail[mail_smtpport]" size="5" maxlength="5" value="587">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPAUTH_REQ']}</label>
|
||||
<input type="checkbox" name="smtp_tab_gmail[mail_smtpauth_req]" id="smtp_tab_gmail__mail_smtpauth_req" value="1" checked="checked" onclick="toggleSMTPAuthSettings(this, 'toggleArea_1');">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EMAIL_SMTP_SSL_OR_TLS']}</label>
|
||||
<select name="smtp_tab_gmail[mail_smtpssl]">
|
||||
{$MAIL_SSL_OPTIONS_GMAIL}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
|
||||
<div class="toggleArea" id="toggleArea_1">
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_GMAIL_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_gmail[mail_smtpuser]" id="smtp_tab_gmail__mail_smtpuser" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_GMAIL_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_gmail[mail_smtppass]" id="smtp_tab_gmail__mail_smtppass" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input name="smtp_tab_gmail[notify_allow_default_outbound]" id="smtp_tab_gmail__notify_allow_default_outbound" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!-- smtp / yahoo! mail tab -->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_yahoo">
|
||||
|
||||
<input type="hidden" name="smtp_tab_yahoo[mail_smtpserver]" size="25" maxlength="255" value="smtp.mail.yahoo.com">
|
||||
<input type="text" name="smtp_tab_yahoo[mail_smtpport]" size="5" maxlength="5" value="465">
|
||||
<input type="hidden" name="smtp_tab_yahoo[mail_smtpssl]" value="1">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_YAHOOMAIL_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_yahoo[mail_smtpuser]" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_YAHOOMAIL_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_yahoo[mail_smtppass]" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input name="smtp_tab_yahoo[notify_allow_default_outbound]" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!-- smtp / ms-exchange tab -->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_exchange">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPSERVER']}</label>
|
||||
<input type="text" name="smtp_tab_exchange[mail_smtpserver]" size="25" maxlength="255" value="">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPPORT']}</label>
|
||||
<input type="text" name="smtp_tab_exchange[mail_smtpport]" size="5" maxlength="5" value="25">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPAUTH_REQ']}</label>
|
||||
<input type="checkbox" name="smtp_tab_exchange[mail_smtpauth_req]" id="smtp_tab_exchange__mail_smtpauth_req" value="1" checked="checked" onclick="toggleSMTPAuthSettings(this, 'toggleArea_2');">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EMAIL_SMTP_SSL_OR_TLS']}</label>
|
||||
<select name="smtp_tab_exchange[mail_smtpssl]" tabindex="501">
|
||||
{$MAIL_SSL_OPTIONS_EXCHG}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="toggleArea" id="toggleArea_2">
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_exchange[mail_smtpuser]" id="smtp_tab_exchange__mail_smtpuser" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EXCHANGE_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_exchange[mail_smtppass]" id="smtp_tab_exchange__mail_smtppass" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input name="smtp_tab_exchange[notify_allow_default_outbound]" id="smtp_tab_exchange__notify_allow_default_outbound" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!-- smtp / other tab-->
|
||||
|
||||
<div class="form_section smtp_tab" id="smtp_tab_other">
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPSERVER']}</label>
|
||||
<input type="text" name="smtp_tab_other[mail_smtpserver]" size="25" maxlength="255" value="">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPPORT']}</label>
|
||||
<input type="text" name="smtp_tab_other[mail_smtpport]" size="5" maxlength="5" value="25">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPAUTH_REQ']}</label>
|
||||
<input type="hidden" name="smtp_tab_other[mail_smtpauth_req]" value="0">
|
||||
<input type="checkbox" id="mail_smtpauth_req_chk" name="smtp_tab_other[mail_smtpauth_req]" value="1" checked="checked" onclick="toggleSMTPAuthSettings(this, 'toggleArea_3');">
|
||||
</div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_EMAIL_SMTP_SSL_OR_TLS']}</label>
|
||||
<select name="smtp_tab_other[mail_smtpssl]" tabindex="501">
|
||||
{$MAIL_SSL_OPTIONS_OTHER}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="toggleArea" id="toggleArea_3">
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPUSER']}</label>
|
||||
<input type="text" name="smtp_tab_other[mail_smtpuser]" id="smtp_tab_other__mail_smtpuser" size="25" maxlength="255">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_MAIL_SMTPPASS']}</label>
|
||||
<input type="password" name="smtp_tab_other[mail_smtppass]" id="smtp_tab_other__mail_smtppass" size="25" maxlength="255" value="" tabindex="1">
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<div class="formrow">
|
||||
<label>{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION']} <i>i<div class="tooltip">{$mod_strings['LBL_ALLOW_DEFAULT_SELECTION_HELP']}</div></i></label>
|
||||
<input type="hidden" name="smtp_tab_other[notify_allow_default_outbound]" value="0">
|
||||
<input id="notify_allow_default_outbound_chk" name="smtp_tab_other[notify_allow_default_outbound]" value="2" tabindex="1" class="checkbox" type="checkbox" {$notify_allow_default_outbound_checked}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
<!-- </div> -->
|
||||
|
||||
<!-- smtp default values & tabs toggler js & tooltip help -->
|
||||
|
||||
<script>
|
||||
|
||||
var toggleSMTPAuthFields = {
|
||||
toggleArea_1 : {
|
||||
user: 'smtp_tab_gmail__mail_smtpuser',
|
||||
pass: 'smtp_tab_gmail__mail_smtppass',
|
||||
allow: 'smtp_tab_gmail__notify_allow_default_outbound'
|
||||
},
|
||||
toggleArea_2 : {
|
||||
user: 'smtp_tab_exchange__mail_smtpuser',
|
||||
pass: 'smtp_tab_exchange__mail_smtppass',
|
||||
allow: 'smtp_tab_exchange__notify_allow_default_outbound'
|
||||
},
|
||||
toggleArea_3 : {
|
||||
user: 'smtp_tab_other__mail_smtpuser',
|
||||
pass: 'smtp_tab_other__mail_smtppass',
|
||||
allow: 'notify_allow_default_outbound_chk'
|
||||
}
|
||||
};
|
||||
|
||||
var toggleSMTPAuthSettings = function(chkbox, elemID) {
|
||||
if($(chkbox).prop('checked')) {
|
||||
$('#' + elemID).show();
|
||||
}
|
||||
else {
|
||||
$('#' + toggleSMTPAuthFields[elemID].user).val('');
|
||||
$('#' + toggleSMTPAuthFields[elemID].pass).val('');
|
||||
$('#' + toggleSMTPAuthFields[elemID].allow).prop('checked', false);
|
||||
$('#' + elemID).hide();
|
||||
}
|
||||
};
|
||||
|
||||
$(function(){
|
||||
|
||||
$('.smtp_tab_toggler').click(function(){
|
||||
$('.smtp_tab_toggler.selected').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
$('.smtp_tab').hide();
|
||||
$('#'+$(this).attr('for')).show();
|
||||
$('input[name="smtp_tab_selected"]').val($(this).attr('for'));
|
||||
});
|
||||
|
||||
// save last selected tab and set as default when form (re)load
|
||||
$('#{$_SESSION['smtp_tab_selected']}_toggler').click();
|
||||
|
||||
$('select[name="smtp_tab_gmail[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
$('select[name="smtp_tab_yahoo[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
$('select[name="smtp_tab_exchange[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
$('select[name="smtp_tab_other[mail_smtpssl]"] option').each(function(){
|
||||
if(!$(this).html()) {
|
||||
$(this).html('-none-');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
toggleSMTPAuthSettings(document.getElementById('smtp_tab_gmail__mail_smtpauth_req'), 'toggleArea_1');
|
||||
toggleSMTPAuthSettings(document.getElementById('smtp_tab_exchange__mail_smtpauth_req'), 'toggleArea_2');
|
||||
toggleSMTPAuthSettings(document.getElementById('mail_smtpauth_req_chk'), 'toggleArea_3');
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
</div> <!-- toggle hidden box end -->
|
||||
EOQ;
|
||||
|
||||
|
||||
// db setup (dbConfig_a.php)
|
||||
$out2 =<<<EOQ2
|
||||
<input type='hidden' name='setup_db_drop_tables' id='setup_db_drop_tables' value=''>
|
||||
|
@ -956,8 +619,6 @@ EOQ2;
|
|||
$out .= <<<EOQ
|
||||
|
||||
<!-- Branding -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="floatbox full" id="fb3">
|
||||
<h3 onclick="$(this).next().toggle();" class="toggler">» {$mod_strings['LBL_WIZARD_SYSTEM_TITLE']}</h3>
|
||||
|
||||
|
|
|
@ -1031,6 +1031,8 @@ EOQ;
|
|||
RewriteBase {$basePath}
|
||||
RewriteRule ^cache/jsLanguage/(.._..).js$ index.php?entryPoint=jslang&modulename=app_strings&lang=$1 [L,QSA]
|
||||
RewriteRule ^cache/jsLanguage/(\w*)/(.._..).js$ index.php?entryPoint=jslang&modulename=$1&lang=$2 [L,QSA]
|
||||
|
||||
RewriteRule ^ep/(.*?)$ index.php?entryPoint=$1 [L,QSA]
|
||||
|
||||
# --------- DEPRECATED --------
|
||||
RewriteRule ^api/(.*)$ - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
|
|
@ -143,6 +143,7 @@ class SearchResults
|
|||
|
||||
$obj->load_relationships();
|
||||
$fieldDefs = $obj->getFieldDefinitions();
|
||||
$obj = $this->formatForDisplay($obj, $fieldDefs);
|
||||
$parsed[$module][] = $this->updateFieldDefLinks($obj, $fieldDefs);
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +151,68 @@ class SearchResults
|
|||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format data so it can be correctly displayed on search results
|
||||
*
|
||||
* @param SugarBean $obj
|
||||
* @param array $fieldDefs
|
||||
* @return SugarBean
|
||||
*/
|
||||
protected function formatForDisplay(SugarBean $obj, array $fieldDefs): SugarBean
|
||||
{
|
||||
global $app_list_strings, $locale;
|
||||
|
||||
foreach ($fieldDefs as $fieldDef) {
|
||||
$value = $obj->{$fieldDef['name']};
|
||||
if (isset($value)) {
|
||||
switch ($fieldDef['type']){
|
||||
case 'enum':
|
||||
case 'dynamicenum':
|
||||
|
||||
if (isset($app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']][$value]) &&
|
||||
isset($obj->field_name_map[$fieldDef['name']]['options'])
|
||||
) {
|
||||
$obj->{$fieldDef['name']} = $app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']][$value];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'multienum':
|
||||
|
||||
if (isset($obj->field_name_map[$fieldDef['name']]['options']) &&
|
||||
isset($app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']])
|
||||
) {
|
||||
$multienumString = '';
|
||||
$multienumValues = unencodeMultienum($value);
|
||||
$arrayCount = count($multienumValues);
|
||||
$i = 0;
|
||||
foreach ($multienumValues as $multienumValue) {
|
||||
$i++;
|
||||
$multienumString .= $app_list_strings[$obj->field_name_map[$fieldDef['name']]['options']][$multienumValue];
|
||||
if($i !== ($arrayCount)) $multienumString .= ", ";
|
||||
}
|
||||
$obj->{$fieldDef['name']} = $multienumString;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'currency':
|
||||
|
||||
if (substr($fieldDef['name'], -9) !== '_usdollar') {
|
||||
$params['currency_id'] = getCurrencyId($obj->module_dir, $obj->id);
|
||||
$params['currency_symbol'] = $locale->currencies[$params['currency_id']]['symbol'];
|
||||
} else {
|
||||
$params['currency_id'] = $locale->getPrecedentPreference('currency');
|
||||
$params['currency_symbol'] = $locale->getPrecedentPreference('default_currency_symbol');
|
||||
$params['convert'] = true;
|
||||
}
|
||||
$obj->{$fieldDef['name']} = currency_format_number($value, $params);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param SugarBean $obj
|
||||
|
@ -210,7 +273,12 @@ class SearchResults
|
|||
{
|
||||
$relField = $idName;
|
||||
if (isset($obj->$link)) {
|
||||
$relId = $obj->$link->getFocus()->$relField;
|
||||
$linkedBeans = $obj->$link->getBeans();
|
||||
if(count($linkedBeans) === 1){
|
||||
$relId = array_keys($linkedBeans)[0];
|
||||
} else {
|
||||
$relId = $obj->$link->getFocus()->$relField;
|
||||
}
|
||||
if (is_object($relId)) {
|
||||
if (method_exists($relId, "getFocus")) {
|
||||
$relId = $relId->getFocus()->id;
|
||||
|
@ -242,9 +310,9 @@ class SearchResults
|
|||
*/
|
||||
protected function getLink(string $label, string $module, string $record, string $action): string
|
||||
{
|
||||
global $sugar_config;
|
||||
|
||||
return "<a href=\"{$sugar_config['site_url']}/index.php?action={$action}&module={$module}&record={$record}&offset=1\"><span>{$label}</span></a>";
|
||||
$link = ajaxLink("index.php?action={$action}&module={$module}&record={$record}");
|
||||
|
||||
return "<a href=\"{$link}\"><span>{$label}</span></a>";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,8 +143,15 @@ class SearchResultsController extends Controller
|
|||
$smarty->assign('results', $this->results);
|
||||
$smarty->assign('APP', $app_strings);
|
||||
$smarty->assign('SITE_URL', $siteUrl);
|
||||
$moduleName = [];
|
||||
try {
|
||||
$smarty->assign('resultsAsBean', $this->results->getHitsAsBeans());
|
||||
$hitsAsBeans = $this->results->getHitsAsBeans();
|
||||
foreach($hitsAsBeans as $bean){
|
||||
$moduleName[$bean[0]->module_name] = translate('LBL_MODULE_NAME', $bean[0]->module_name);
|
||||
}
|
||||
$smarty->assign('moduleLabel', $moduleName);
|
||||
|
||||
$smarty->assign('resultsAsBean', $hitsAsBeans);
|
||||
} catch (\SuiteCRM\Exception\Exception $e) {
|
||||
LoggerManager::getLogger()->fatal("Failed to retrieve ElasticSearch options");
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
{/if}
|
||||
|
||||
{foreach from=$resultsAsBean item=beans key=module}
|
||||
<h3>{$module}</h3>
|
||||
<h3>{$moduleLabel[$module]}</h3>
|
||||
<table class="list view">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -406,7 +406,6 @@ EOF;
|
|||
options: {
|
||||
grouping:'$grouping',
|
||||
backgroundGrid:false,
|
||||
backgroundGrid:false,
|
||||
gutterBottom: 150,
|
||||
gutterTop:25,
|
||||
gutterLeft:128,
|
||||
|
|
|
@ -56,10 +56,10 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path),['allowed_classes' => false]);
|
||||
$html .= "report_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->report_module, $condition_name->module_path[0]))))."\";";
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
@ -84,9 +84,9 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path),['allowed_classes' => false]);
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
|
|
@ -61,7 +61,7 @@ function display_field_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$field_name = BeanFactory::newBean('AOR_Fields');
|
||||
$field_name->retrieve($row['id']);
|
||||
$field_name->module_path = unserialize(base64_decode($field_name->module_path));
|
||||
$field_name->module_path = unserialize(base64_decode($field_name->module_path),['allowed_classes' => false]);
|
||||
$html .= "report_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->report_module, $field_name->module_path[0]))))."\";";
|
||||
$field_item = json_encode($field_name->toArray());
|
||||
$html .= "loadFieldLine(".$field_item.");";
|
||||
|
|
|
@ -204,8 +204,8 @@ class AOR_Report extends Basic
|
|||
while ($row = $this->db->fetchByAssoc($result)) {
|
||||
$field = BeanFactory::newBean('AOR_Fields');
|
||||
$field->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
|
||||
|
@ -311,7 +311,7 @@ class AOR_Report extends Basic
|
|||
$GLOBALS['log']->fatal('ambiguous group display for report ' . $this->id);
|
||||
} else {
|
||||
if ($rowsCount == 1) {
|
||||
$rows[0]['module_path'] = unserialize(base64_decode($rows[0]['module_path']));
|
||||
$rows[0]['module_path'] = unserialize(base64_decode($rows[0]['module_path']),['allowed_classes' => false]);
|
||||
if (!$rows[0]['module_path'][0]) {
|
||||
$module = new $beanList[$this->report_module]();
|
||||
$rows[0]['field_id_name'] = $module->field_defs[$rows[0]['field']]['id_name'] ? $module->field_defs[$rows[0]['field']]['id_name'] : $module->field_defs[$rows[0]['field']]['name'];
|
||||
|
@ -440,7 +440,7 @@ class AOR_Report extends Basic
|
|||
|
||||
$field_label = str_replace(' ', '_', (string) $field->label);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_module = $module;
|
||||
$table_alias = $field_module->table_name;
|
||||
|
@ -670,7 +670,7 @@ class AOR_Report extends Basic
|
|||
$field = BeanFactory::newBean('AOR_Fields');
|
||||
$field->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
|
||||
|
@ -905,7 +905,7 @@ class AOR_Report extends Basic
|
|||
// End
|
||||
}
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
|
||||
|
@ -1047,7 +1047,7 @@ class AOR_Report extends Basic
|
|||
$field = BeanFactory::newBean('AOR_Fields');
|
||||
$field->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
$field_bean = new $beanList[$this->report_module]();
|
||||
$field_module = $this->report_module;
|
||||
$field_alias = $field_bean->table_name;
|
||||
|
@ -1240,9 +1240,7 @@ class AOR_Report extends Basic
|
|||
|
||||
$field->label = str_replace(' ', '_', (string) $field->label) . $i;
|
||||
|
||||
$path = unserialize(base64_decode($field->module_path));
|
||||
|
||||
$data = $field_module->field_defs[$field->field] ?? [];
|
||||
$path = unserialize(base64_decode($field->module_path),['allowed_classes' => false]);
|
||||
|
||||
$field_module = $module;
|
||||
$table_alias = $field_module->table_name;
|
||||
|
@ -1265,7 +1263,7 @@ class AOR_Report extends Basic
|
|||
$field_module = $new_field_module;
|
||||
}
|
||||
}
|
||||
|
||||
$data = $field_module->field_defs[$field->field] ?? [];
|
||||
|
||||
if (!empty($data)){
|
||||
if ($data['type'] == 'relate' && isset($data['id_name'])) {
|
||||
|
@ -1340,10 +1338,11 @@ class AOR_Report extends Basic
|
|||
unset($query['id_select'][$table_alias]);
|
||||
}
|
||||
|
||||
if ($field->group_by == 1) {
|
||||
if ($field->field_function != null) {
|
||||
$unique = $field->group_by == 1 ? 'DISTINCT ' : '';
|
||||
$select_field = $field->field_function . '(' . $unique . $select_field . ')';
|
||||
} elseif ($field->group_by == 1) {
|
||||
$query['group_by'][] = $select_field;
|
||||
} elseif ($field->field_function != null) {
|
||||
$select_field = $field->field_function . '(' . $select_field . ')';
|
||||
} else {
|
||||
$query['second_group_by'][] = $select_field;
|
||||
}
|
||||
|
@ -1490,14 +1489,14 @@ class AOR_Report extends Basic
|
|||
$condition = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path),['allowed_classes' => false]);
|
||||
|
||||
$condition_module = $module;
|
||||
$table_alias = $condition_module->table_name;
|
||||
$oldAlias = $table_alias;
|
||||
if (!empty($path[0]) && $path[0] != $module->module_dir) {
|
||||
foreach ($path as $rel) {
|
||||
if (empty($rel)) {
|
||||
if (empty($rel) || !is_string($rel)) {
|
||||
continue;
|
||||
}
|
||||
// Bug: Prevents relationships from loading.
|
||||
|
@ -1629,7 +1628,7 @@ class AOR_Report extends Basic
|
|||
break;
|
||||
|
||||
case 'Date':
|
||||
$params = unserialize(base64_decode($condition->value));
|
||||
$params = unserialize(base64_decode($condition->value),['allowed_classes' => false]);
|
||||
|
||||
// Fix for issue #1272 - AOR_Report module cannot update Date type parameter.
|
||||
if ($params == false) {
|
||||
|
|
|
@ -185,7 +185,7 @@ function getConditionsAsParameters($report, $override = array())
|
|||
continue;
|
||||
}
|
||||
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path),['allowed_classes' => false]);
|
||||
$field_module = $report->report_module;
|
||||
if ($path[0] != $report->report_module) {
|
||||
foreach ($path as $rel) {
|
||||
|
@ -196,7 +196,7 @@ function getConditionsAsParameters($report, $override = array())
|
|||
}
|
||||
}
|
||||
|
||||
$additionalConditions = unserialize(base64_decode($condition->value));
|
||||
$additionalConditions = unserialize(base64_decode($condition->value),['allowed_classes' => false]);
|
||||
|
||||
|
||||
$value = isset($override[$condition->id]['value']) ? $override[$condition->id]['value'] : $value = $condition->value;
|
||||
|
|
|
@ -38,9 +38,9 @@ class AOR_ReportsViewDetail extends ViewDetail
|
|||
if (!$condition->parameter) {
|
||||
continue;
|
||||
}
|
||||
$condition->module_path = implode(":", unserialize(base64_decode($condition->module_path)));
|
||||
$condition->module_path = implode(":", unserialize(base64_decode($condition->module_path),['allowed_classes' => false]));
|
||||
if ($condition->value_type == 'Date') {
|
||||
$condition->value = unserialize(base64_decode($condition->value));
|
||||
$condition->value = unserialize(base64_decode($condition->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = $condition->toArray();
|
||||
$display = getDisplayForField($condition->module_path, $condition->field, $this->bean->report_module);
|
||||
|
|
|
@ -82,10 +82,10 @@ class AOR_ReportsViewEdit extends ViewEdit
|
|||
$condition_name = BeanFactory::newBean('AOR_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
if (!$condition_name->parenthesis) {
|
||||
$condition_name->module_path = implode(":", unserialize(base64_decode($condition_name->module_path)));
|
||||
$condition_name->module_path = implode(":", unserialize(base64_decode($condition_name->module_path),['allowed_classes' => false]));
|
||||
}
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value),['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = $condition_name->toArray();
|
||||
|
||||
|
@ -115,7 +115,7 @@ class AOR_ReportsViewEdit extends ViewEdit
|
|||
while ($row = $this->bean->db->fetchByAssoc($result)) {
|
||||
$field_name = BeanFactory::newBean('AOR_Fields');
|
||||
$field_name->retrieve($row['id']);
|
||||
$field_name->module_path = implode(":", unserialize(base64_decode($field_name->module_path)));
|
||||
$field_name->module_path = implode(":", unserialize(base64_decode($field_name->module_path),['allowed_classes' => false]));
|
||||
$arr = $field_name->toArray();
|
||||
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ class AOR_Scheduled_Reports extends basic
|
|||
|
||||
public function get_email_recipients()
|
||||
{
|
||||
$params = unserialize(base64_decode($this->email_recipients));
|
||||
$params = unserialize(base64_decode($this->email_recipients),['allowed_classes' => false]);
|
||||
|
||||
$emails = array();
|
||||
if (isset($params['email_target_type'])) {
|
||||
|
|
|
@ -42,7 +42,7 @@ function display_email_lines($focus, $field, $value, $view)
|
|||
{
|
||||
global $app_list_strings;
|
||||
$aorEmailToList = $app_list_strings['aor_email_to_list'] ?? '';
|
||||
$params = unserialize(base64_decode($value));
|
||||
$params = unserialize(base64_decode($value),['allowed_classes' => false]);
|
||||
|
||||
if ($view == 'EditView') {
|
||||
$html = '<script src="modules/AOR_Scheduled_Reports/emailRecipients.js"></script>';
|
||||
|
|
|
@ -67,7 +67,7 @@ class templateParser
|
|||
if (isset($field_def['name']) && $field_def['name'] != '') {
|
||||
$fieldName = $field_def['name'];
|
||||
|
||||
if (empty($focus->$fieldName)) {
|
||||
if (!isset($focus->$fieldName) || $focus->$fieldName === '') {
|
||||
$repl_arr[$key . '_' . $fieldName] = '';
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ function display_lines($focus, $field, $value, $view)
|
|||
if ($serviceCount == 0) {
|
||||
$service .= "<tr>";
|
||||
$service .= "<td width='5%' class='tabDetailViewDL' style='text-align: left;padding:2px;' scope='row'> </td>";
|
||||
$service .= "<td width='46%' class='dataLabel' style='text-align: left;padding:2px;' colspan='2' scope='row'>".$mod_strings['LBL_SERVICE_NAME']."</td>";
|
||||
$service .= "<td width='22%' class='dataLabel' style='text-align: left;padding:2px;' colspan='2' scope='row'>".$mod_strings['LBL_SERVICE_NAME']."</td>";
|
||||
$service .= "<td width='12%' class='dataLabel' style='text-align: right;padding:2px;' scope='row'>".$mod_strings['LBL_SERVICE_LIST_PRICE']."</td>";
|
||||
$service .= "<td width='12%' class='dataLabel' style='text-align: right;padding:2px;' scope='row'>".$mod_strings['LBL_SERVICE_DISCOUNT']."</td>";
|
||||
$service .= "<td width='12%' class='dataLabel' style='text-align: right;padding:2px;' scope='row'>".$mod_strings['LBL_SERVICE_PRICE']."</td>";
|
||||
|
|
|
@ -57,13 +57,13 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOW_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path), ['allowed_classes' => false]);
|
||||
if ($condition_name->module_path == '') {
|
||||
$condition_name->module_path = $focus->flow_module;
|
||||
}
|
||||
$html .= "flow_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->flow_module, $condition_name->module_path[0]))))."\";";
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value), ['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
@ -88,13 +88,13 @@ function display_condition_lines($focus, $field, $value, $view)
|
|||
while ($row = $focus->db->fetchByAssoc($result)) {
|
||||
$condition_name = BeanFactory::newBean('AOW_Conditions');
|
||||
$condition_name->retrieve($row['id']);
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path));
|
||||
$condition_name->module_path = unserialize(base64_decode($condition_name->module_path), ['allowed_classes' => false]);
|
||||
if (empty($condition_name->module_path)) {
|
||||
$condition_name->module_path[0] = $focus->flow_module;
|
||||
}
|
||||
$html .= "flow_fields = \"".trim(preg_replace('/\s+/', ' ', (string) getModuleFields(getRelatedModule($focus->flow_module, $condition_name->module_path[0]))))."\";";
|
||||
if ($condition_name->value_type == 'Date') {
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value));
|
||||
$condition_name->value = unserialize(base64_decode($condition_name->value), ['allowed_classes' => false]);
|
||||
}
|
||||
$condition_item = json_encode($condition_name->toArray());
|
||||
$html .= "loadConditionLine(".$condition_item.");";
|
||||
|
|
|
@ -389,7 +389,7 @@ class AOW_WorkFlow extends Basic
|
|||
public function build_query_where(AOW_Condition $condition, $module, $query = array())
|
||||
{
|
||||
global $beanList, $app_list_strings, $sugar_config, $timedate;
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path), ['allowed_classes' => false]);
|
||||
|
||||
$condition_module = $module;
|
||||
$table_alias = $condition_module->table_name;
|
||||
|
@ -514,7 +514,7 @@ class AOW_WorkFlow extends Basic
|
|||
return array();
|
||||
case 'Date':
|
||||
|
||||
$params = @unserialize(base64_decode($condition->value));
|
||||
$params = @unserialize(base64_decode($condition->value), ['allowed_classes' => false]);
|
||||
if ($params === false) {
|
||||
LoggerManager::getLogger()->error('Unserializable data given');
|
||||
$params = [null];
|
||||
|
@ -749,7 +749,7 @@ class AOW_WorkFlow extends Basic
|
|||
$condition = BeanFactory::newBean('AOW_Conditions');
|
||||
$condition->retrieve($row['id']);
|
||||
|
||||
$path = unserialize(base64_decode($condition->module_path));
|
||||
$path = unserialize(base64_decode($condition->module_path), ['allowed_classes' => false]);
|
||||
|
||||
$condition_bean = $bean;
|
||||
|
||||
|
@ -815,7 +815,7 @@ class AOW_WorkFlow extends Basic
|
|||
break;
|
||||
|
||||
case 'Date':
|
||||
$params = unserialize(base64_decode($value));
|
||||
$params = unserialize(base64_decode($value), ['allowed_classes' => false]);
|
||||
$dateType = 'datetime';
|
||||
if ($params[0] == 'now') {
|
||||
$value = date('Y-m-d H:i:s');
|
||||
|
@ -1055,7 +1055,7 @@ class AOW_WorkFlow extends Basic
|
|||
|
||||
|
||||
$flow_action = new $action_name($action->id);
|
||||
if (!$flow_action->run_action($bean, unserialize(base64_decode($action->parameters)), $in_save)) {
|
||||
if (!$flow_action->run_action($bean, unserialize(base64_decode($action->parameters), ['allowed_classes' => false]), $in_save)) {
|
||||
$pass = false;
|
||||
$processed->aow_actions->add($action->id, array('status' => 'Failed'));
|
||||
} else {
|
||||
|
|
|
@ -559,7 +559,7 @@ class AOW_WorkFlowController extends SugarController
|
|||
$aow_action = BeanFactory::newBean('AOW_Actions');
|
||||
$aow_action->retrieve($_REQUEST['id']);
|
||||
$id = $aow_action->id;
|
||||
$params = unserialize(base64_decode($aow_action->parameters ?? ''));
|
||||
$params = unserialize(base64_decode($aow_action->parameters ?? ''), ['allowed_classes' => false]);
|
||||
|
||||
if ($params === false) {
|
||||
$params = [];
|
||||
|
|
|
@ -203,7 +203,7 @@ if ($mail->Mailer == 'smtp' && $mail->Host == '') {
|
|||
|
||||
$focus = BeanFactory::newBean('InboundEmail');
|
||||
$focus->checkImap();
|
||||
$storedOptions = unserialize(base64_decode($focus->stored_options ?? ''));
|
||||
$storedOptions = unserialize(base64_decode($focus->stored_options ?? ''), ['allowed_classes' => false]);
|
||||
$email_templates_arr = get_bean_select_array(true, 'EmailTemplate', 'name', '', 'name', true);
|
||||
$create_case_email_template = (isset($storedOptions['create_case_email_template'])) ? $storedOptions['create_case_email_template'] : "";
|
||||
$TMPL_DRPDWN_LOST = get_select_options_with_id($email_templates_arr, $res['lostpasswordtmpl']);
|
||||
|
|
|
@ -66,7 +66,8 @@ class Controller extends AbstractController
|
|||
*/
|
||||
public function doSave(): void
|
||||
{
|
||||
$searchEngine = filter_input(INPUT_POST, 'search-engine');
|
||||
$searchEngine = filter_input(INPUT_POST, 'search-engine', FILTER_SANITIZE_STRING);
|
||||
$aod = $searchEngine === 'BasicAndAodEngine';
|
||||
|
||||
SearchConfigurator::make()
|
||||
->setEngine($searchEngine)
|
||||
|
|
|
@ -98,7 +98,7 @@ $has_updates= false;
|
|||
if (!empty($license->settings['license_latest_versions'])) {
|
||||
$encodedVersions = $license->settings['license_latest_versions'];
|
||||
|
||||
$versions = unserialize(base64_decode($encodedVersions));
|
||||
$versions = unserialize(base64_decode($encodedVersions), ['allowed_classes' => false]);
|
||||
include('sugar_version.php');
|
||||
if (!empty($versions)) {
|
||||
foreach ($versions as $version) {
|
||||
|
|
|
@ -78,7 +78,7 @@ while ($row = $db->fetchByAssoc($result)) {
|
|||
$prefs = array();
|
||||
$newprefs = array();
|
||||
|
||||
$prefs = unserialize(base64_decode($row['user_preferences']));
|
||||
$prefs = unserialize(base64_decode($row['user_preferences']), ['allowed_classes' => false]);
|
||||
$setTo = '';
|
||||
$alreadySet = '';
|
||||
if (!empty($prefs)) {
|
||||
|
|
|
@ -196,7 +196,7 @@ function check_now($send_usage_info=true, $get_request_data=false, $response_dat
|
|||
|
||||
if ($response_data || !$sclient->getError()) {
|
||||
$serializedResultData = sugarDecode($key, $encodedResult);
|
||||
$resultData = unserialize($serializedResultData);
|
||||
$resultData = unserialize($serializedResultData, ['allowed_classes' => false]);
|
||||
if ($response_data && empty($resultData)) {
|
||||
$resultData = array();
|
||||
$resultData['validation'] = 'invalid validation key';
|
||||
|
|
|
@ -231,7 +231,7 @@ class CalendarDisplay
|
|||
if (empty($activity)) {
|
||||
$activity = $this->activity_colors;
|
||||
}
|
||||
$newActivities = unserialize(base64_decode($current_user->getPreference("CalendarActivities") ?? ''));
|
||||
$newActivities = unserialize(base64_decode($current_user->getPreference("CalendarActivities") ?? ''), ['allowed_classes' => false]);
|
||||
if ($newActivities) {
|
||||
$activity = array_merge($activity, $newActivities);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ function get_campaign_mailboxes_with_stored_options()
|
|||
$r = $db->query($q);
|
||||
|
||||
while ($a = $db->fetchByAssoc($r)) {
|
||||
$ret[$a['id']] = unserialize(base64_decode($a['stored_options']));
|
||||
$ret[$a['id']] = unserialize(base64_decode($a['stored_options']), ['allowed_classes' => false]);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
|
|
@ -49,21 +49,28 @@ class TemplateDatetimecombo extends TemplateRange
|
|||
{
|
||||
public $type = 'datetimecombo';
|
||||
public $len = '';
|
||||
public $dateStrings = array(
|
||||
'-none-' => '',
|
||||
'today'=>'now',
|
||||
'yesterday'=> '-1 day',
|
||||
'tomorrow'=>'+1 day',
|
||||
'next week'=> '+1 week',
|
||||
'next monday'=>'next monday',
|
||||
'next friday'=>'next friday',
|
||||
'two weeks'=> '+2 weeks',
|
||||
'next month'=> '+1 month',
|
||||
'first day of next month'=> 'first of next month', // must handle this non-GNU date string in SugarBean->populateDefaultValues; if we don't this will evaluate to 1969...
|
||||
'three months'=> '+3 months', //kbrill Bug #17023
|
||||
'six months'=> '+6 months',
|
||||
'next year'=> '+1 year',
|
||||
);
|
||||
public $dateStrings;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
global $app_strings;
|
||||
$this->dateStrings = array(
|
||||
$app_strings['LBL_NONE']=>'',
|
||||
$app_strings['LBL_YESTERDAY']=> '-1 day',
|
||||
$app_strings['LBL_TODAY']=>'now',
|
||||
$app_strings['LBL_TOMORROW']=>'+1 day',
|
||||
$app_strings['LBL_NEXT_WEEK']=> '+1 week',
|
||||
$app_strings['LBL_NEXT_MONDAY']=>'next monday',
|
||||
$app_strings['LBL_NEXT_FRIDAY']=>'next friday',
|
||||
$app_strings['LBL_TWO_WEEKS']=> '+2 weeks',
|
||||
$app_strings['LBL_NEXT_MONTH']=> '+1 month',
|
||||
$app_strings['LBL_FIRST_DAY_OF_NEXT_MONTH']=> 'first day of next month', // must handle this non-GNU date string in SugarBean->populateDefaultValues; if we don't this will evaluate to 1969...
|
||||
$app_strings['LBL_THREE_MONTHS']=> '+3 months', //kbrill Bug #17023
|
||||
$app_strings['LBL_SIXMONTHS']=> '+6 months',
|
||||
$app_strings['LBL_NEXT_YEAR']=> '+1 year',
|
||||
);
|
||||
}
|
||||
|
||||
public $hoursStrings = array(
|
||||
'' => '',
|
||||
|
|
|
@ -153,7 +153,7 @@ class TemplateEnum extends TemplateText
|
|||
$def['studio'] = 'visible';
|
||||
// this class may be extended, so only do the unserialize for genuine TemplateEnums
|
||||
if (get_class($this) == 'TemplateEnum' && empty($def['dependency'])) {
|
||||
$def['dependency'] = $this->ext4 !== null? unserialize(html_entity_decode((string) $this->ext4)) : null ;
|
||||
$def['dependency'] = $this->ext4 !== null? unserialize(html_entity_decode((string) $this->ext4), ['allowed_classes' => false]) : null ;
|
||||
}
|
||||
if (!empty($this->visibility_grid)) {
|
||||
$def['visibility_grid'] = $this->visibility_grid;
|
||||
|
|
|
@ -128,7 +128,7 @@ class TemplateMultiEnum extends TemplateEnum
|
|||
// turn off error reporting in case we are unpacking a value that hasn't been packed...
|
||||
// this is kludgy, but unserialize doesn't throw exceptions correctly
|
||||
if ($this->ext4[0] == 'a' && $this->ext4[1] == ':') {
|
||||
$unpacked = @unserialize($this->ext4) ;
|
||||
$unpacked = @unserialize($this->ext4, ['allowed_classes' => false]) ;
|
||||
} else {
|
||||
$unpacked = false;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ require_once('modules/Notes/Note.php');
|
|||
$note = BeanFactory::newBean('Notes');
|
||||
//check if file is an email image
|
||||
if (!$note->retrieve_by_string_fields(array('id' => $_REQUEST['id'], 'parent_type' => "Emails"))) {
|
||||
//die("Not a Valid Entry Point");
|
||||
die("Not a Valid Entry Point");
|
||||
}
|
||||
|
||||
$location = $GLOBALS['sugar_config']['upload_dir']."/" . $_REQUEST['id'];
|
||||
|
|
|
@ -81,8 +81,7 @@ if (isset($admin->settings['massemailer_email_copy'])) {
|
|||
$emailsPerSecond = 10;
|
||||
|
||||
$mail->setMailerForSystem();
|
||||
$mail->From = "no-reply@example.com";
|
||||
$mail->FromName = "no-reply";
|
||||
$mail->setSystemFromAddress();
|
||||
$mail->ContentType = "text/html";
|
||||
|
||||
$campaign_id = null;
|
||||
|
@ -226,32 +225,29 @@ do {
|
|||
$mail->Mailer = 'smtp';
|
||||
$mail->Host = $outboundEmailAccount->mail_smtpserver;
|
||||
$mail->Port = $outboundEmailAccount->mail_smtpport;
|
||||
if ($outboundEmailAccount->mail_smtpssl == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} elseif ($outboundEmailAccount->mail_smtpssl == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} else {
|
||||
$mail->SMTPSecure = '';
|
||||
}
|
||||
if ($outboundEmailAccount->mail_smtpauth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $outboundEmailAccount->mail_smtpuser;
|
||||
$mail->Password = $outboundEmailAccount->mail_smtppass;
|
||||
} else {
|
||||
$mail->SMTPAuth = false;
|
||||
$mail->Username = '';
|
||||
$mail->Password = '';
|
||||
}
|
||||
|
||||
$mail->setSecureProtocol($ssltls ?? false);
|
||||
$mail->initSMTPAuth(
|
||||
$outboundEmailAccount->auth_type ?? '',
|
||||
$outboundEmailAccount->external_oauth_connection_id ?? '',
|
||||
$outboundEmailAccount->mail_smtpuser ?? '',
|
||||
$outboundEmailAccount->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = 'sendmail';
|
||||
}
|
||||
|
||||
$mail->oe->mail_smtpauth_req = $outboundEmailAccount->mail_smtpauth_req;
|
||||
$mail->oe->mail_smtpuser = $outboundEmailAccount->mail_smtpuser;
|
||||
$mail->oe->mail_smtppass = $outboundEmailAccount->mail_smtppass;
|
||||
$mail->oe->mail_smtpserver = $outboundEmailAccount->mail_smtpserver;
|
||||
$mail->oe->mail_smtpport = $outboundEmailAccount->mail_smtpport;
|
||||
$mail->oe->mail_smtpssl = $outboundEmailAccount->mail_smtpssl;
|
||||
$mail->oe->auth_type = $outboundEmailAccount->auth_type ?? '';
|
||||
$mail->oe->external_oauth_connection_id = $outboundEmailAccount->external_oauth_connection_id ?? '';
|
||||
$mail->oe->mail_smtpauth_req = $outboundEmailAccount->mail_smtpauth_req ?? '';
|
||||
$mail->oe->mail_smtpuser = $outboundEmailAccount->mail_smtpuser ?? '';
|
||||
$mail->oe->mail_smtppass = $outboundEmailAccount->mail_smtppass ?? '';
|
||||
$mail->oe->mail_smtpserver = $outboundEmailAccount->mail_smtpserver ?? '';
|
||||
$mail->oe->mail_smtpport = $outboundEmailAccount->mail_smtpport ?? '';
|
||||
$mail->oe->mail_smtpssl = $outboundEmailAccount->mail_smtpssl ?? '';
|
||||
|
||||
$mail->FromName = $outboundEmailAccount->smtp_from_name ?? $outboundEmailAccount->mail_smtpuser;
|
||||
$mail->From = $outboundEmailAccount->smtp_from_address ?? $outboundEmailAccount->mail_smtpuser;
|
||||
}
|
||||
|
||||
if ((empty($row['related_confirm_opt_in']) || $row['related_confirm_opt_in'] == '0')) {
|
||||
|
|
|
@ -61,15 +61,6 @@ class EmailManController extends SugarController
|
|||
$_REQUEST['mail_sendtype'] = "SMTP";
|
||||
}
|
||||
|
||||
// save Outbound settings #Bug 20033 Ensure data for Outbound email exists before trying to update the system mailer.
|
||||
if (isset($_REQUEST['mail_sendtype']) && empty($_REQUEST['campaignConfig'])) {
|
||||
$oe = new OutboundEmail();
|
||||
$oe->populateFromPost();
|
||||
$oe->saveSystem();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$focus = BeanFactory::newBean('Administration');
|
||||
|
||||
if (isset($_POST['tracking_entities_location_type'])) {
|
||||
|
|
|
@ -139,6 +139,7 @@ $mod_strings = array(
|
|||
'LBL_FROM_ADDRESS_HELP' => 'When enabled, the assigning user\\\'s name and email address will be included in the From field of the email. This feature might not work with SMTP servers that do not allow sending from a different email account than the server account.',
|
||||
'LBL_HELP' => 'Help' /*for 508 compliance fix*/,
|
||||
'LBL_OUTBOUND_EMAIL_ACCOUNT_VIEW' => 'View Outbound Email Accounts',
|
||||
'LBL_SYSTEM_OUTBOUND_EMAIL_ACCOUNT' => 'System Outbound Email Account',
|
||||
'LBL_ALLOW_SEND_AS_USER' => 'Users may send as themselves:',
|
||||
'LBL_ALLOW_SEND_AS_USER_DESC' => 'When enabled, <b>all</b> users can send email using the outgoing mail server, using their own primary email address as the "From:" address.<br>This feature might not work with SMTP servers that do not allow sending from a different email account than the server account.',
|
||||
);
|
||||
|
|
|
@ -52,9 +52,22 @@ global $mod_strings;
|
|||
global $app_list_strings;
|
||||
global $app_strings;
|
||||
global $current_user;
|
||||
global $sugar_config;
|
||||
|
||||
$testMaxTimeout = 30; // seconds
|
||||
if (isset($sugar_config['outbound_email_test_max_timeout']) && is_numeric($sugar_config['outbound_email_test_max_timeout'])) {
|
||||
$testMaxTimeout = (int)$sugar_config['outbound_email_test_max_timeout'];
|
||||
}
|
||||
|
||||
ini_set('max_execution_time', $testMaxTimeout);
|
||||
|
||||
$json = getJSONobj();
|
||||
$pass = '';
|
||||
|
||||
if (empty($_REQUEST['mail_smtppass'])) {
|
||||
$_REQUEST['mail_smtppass'] = BeanFactory::getBean('OutboundEmailAccounts', $_REQUEST['record'])?->mail_smtppass ?? '';
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['mail_smtppass'])) {
|
||||
$pass = $_REQUEST['mail_smtppass'];
|
||||
} elseif (isset($_REQUEST['mail_type'])) {
|
||||
|
@ -73,13 +86,15 @@ $out = $email->sendEmailTest(
|
|||
$_REQUEST['mail_smtpserver'],
|
||||
$_REQUEST['mail_smtpport'],
|
||||
$_REQUEST['mail_smtpssl'],
|
||||
($_REQUEST['mail_smtpauth_req'] == 'true' ? 1 : 0),
|
||||
(isTrue($_REQUEST['mail_smtpauth_req']) ? 1 : 0),
|
||||
$_REQUEST['mail_smtpuser'],
|
||||
$pass,
|
||||
$_REQUEST['outboundtest_from_address'],
|
||||
$_REQUEST['outboundtest_to_address'],
|
||||
$_REQUEST['mail_sendtype'],
|
||||
$_REQUEST['mail_from_name']
|
||||
$_REQUEST['mail_from_name'],
|
||||
$_REQUEST['mail_auth_type'] ?? 'no_auth',
|
||||
$_REQUEST['mail_external_oauth_connection_id'] ?? '',
|
||||
);
|
||||
|
||||
$out = $json->encode($out);
|
||||
|
|
|
@ -99,96 +99,39 @@ function change_state(radiobutton) {
|
|||
{$MOD.LBL_OUTGOING_SECTION_HELP}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="{$OUTBOUND_TYPE_CLASS}">
|
||||
<td width="20%" scope="row">{$MOD.LBL_MAIL_SENDTYPE}</td>
|
||||
<td width="30%">
|
||||
<select id="mail_sendtype" name="mail_sendtype" onChange="notify_setrequired(document.ConfigureSettings); SUGAR.user.showHideGmailDefaultLink(this);" tabindex="1">{$mail_sendtype_options}</select>
|
||||
</td>
|
||||
<td scope="row"> </td>
|
||||
<td > </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="25%" scope="row">
|
||||
{$MOD.LBL_SYSTEM_OUTBOUND_EMAIL_ACCOUNT}
|
||||
</td>
|
||||
{if empty($system_outbound_email_id)}
|
||||
<td width="30%">
|
||||
{sugar_link
|
||||
module="OutboundEmailAccounts"
|
||||
label=$APP.LBL_CREATE_BUTTON_LABEL
|
||||
action='Edit'
|
||||
class="btn btn-sm btn-primary"
|
||||
extraparams="type=system"
|
||||
}
|
||||
</td>
|
||||
{/if}
|
||||
{if !empty($system_outbound_email_id)}
|
||||
<td width="30%">
|
||||
{sugar_link
|
||||
module="OutboundEmailAccounts"
|
||||
record=$system_outbound_email_id
|
||||
label=$system_outbound_email_name
|
||||
action='DetailView'
|
||||
}
|
||||
</td>
|
||||
{/if}
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td width="20%" scope="row">{$MOD.LBL_NOTIFY_FROMNAME} <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" > <input id='notify_fromname' name='notify_fromname' tabindex='1' size='25' maxlength='128' type="text" value="{$notify_fromname}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20%" scope="row">{$MOD.LBL_NOTIFY_FROMADDRESS} <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%"><input id='notify_fromaddress' name='notify_fromaddress' tabindex='1' size='25' maxlength='128' type="text" value="{$notify_fromaddress}"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" scope="row" colspan="4">{$MOD.LBL_CHOOSE_EMAIL_PROVIDER}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<div id="smtpButtonGroup" class="yui-buttongroup">
|
||||
<span id="gmail" class="yui-button yui-radio-button{if $mail_smtptype == 'gmail'} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="gmail" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_GMAIL}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span id="yahoomail" class="yui-button yui-radio-button{if $mail_smtptype == 'yahoomail'} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="yahoomail" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_YAHOO}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span id="exchange" class="yui-button yui-radio-button{if $mail_smtptype == 'exchange'} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="exchange" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_EXCHANGE}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
<span id="other" class="yui-button yui-radio-button{if $mail_smtptype == 'other' || empty($mail_smtptype)} yui-button-checked{/if}">
|
||||
<span class="first-child">
|
||||
<button type="button" name="mail_smtptype" value="other" class="btn btn-danger">
|
||||
{$APP.LBL_SMTPTYPE_OTHER}
|
||||
</button>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<td colspan="2">
|
||||
<div id="smtp_settings">
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr id="mailsettings1">
|
||||
<td width="20%" scope="row"><span id="mail_smtpserver_label">{$MOD.LBL_MAIL_SMTPSERVER}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" ><input type="text" id="mail_smtpserver" name="mail_smtpserver" tabindex="1" size="25" maxlength="255" value="{$mail_smtpserver}"></td>
|
||||
<td width="20%" scope="row"><span id="mail_smtpport_label">{$MOD.LBL_MAIL_SMTPPORT}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" ><input type="text" id="mail_smtpport" name="mail_smtpport" tabindex="1" size="5" maxlength="5" value="{$mail_smtpport}"></td>
|
||||
</tr>
|
||||
<tr id="mailsettings2">
|
||||
<td scope="row"><span id='mail_smtpauth_req_label'>{$MOD.LBL_MAIL_SMTPAUTH_REQ}</span></td>
|
||||
<td >
|
||||
<input id='mail_smtpauth_req' name='mail_smtpauth_req' type="checkbox" class="checkbox" value="1" tabindex='1'
|
||||
onclick="notify_setrequired(document.ConfigureSettings);" {$mail_smtpauth_req}>
|
||||
</td>
|
||||
<td width="15%" scope="row"><span id="mail_smtpssl_label">{$APP.LBL_EMAIL_SMTP_SSL_OR_TLS}</span></td>
|
||||
<td width="35%" >
|
||||
<select id="mail_smtpssl" name="mail_smtpssl" tabindex="501" onchange="setDefaultSMTPPort();" >{$MAIL_SSL_OPTIONS}</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="smtp_auth1">
|
||||
<td width="20%" scope="row"><span id="mail_smtpuser_label">{$MOD.LBL_MAIL_SMTPUSER}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" ><input type="text" id="mail_smtpuser" name="mail_smtpuser" size="25" maxlength="255" value="{$mail_smtpuser}" tabindex='1' ></td>
|
||||
<td width="20%"> </td>
|
||||
<td width="30%"> </td>
|
||||
</tr>
|
||||
<tr id="smtp_auth2">
|
||||
<td width="20%" scope="row"><span id="mail_smtppass_label">{$MOD.LBL_MAIL_SMTPPASS}</span> <span class="required">{$APP.LBL_REQUIRED_SYMBOL}</span></td>
|
||||
<td width="30%" >
|
||||
<input type="password" id="mail_smtppass" name="mail_smtppass" size="25" maxlength="255" tabindex='1'>
|
||||
<a href="javascript:void(0)" id='mail_smtppass_link' onClick="SUGAR.util.setEmailPasswordEdit('mail_smtppass')" style="display: none">{$APP.LBL_CHANGE_PASSWORD}</a>
|
||||
</td>
|
||||
<td width="20%"> </td>
|
||||
<td width="30%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr id="mail_allow_user">
|
||||
<td width="25%" scope="row">
|
||||
|
@ -197,7 +140,7 @@ function change_state(radiobutton) {
|
|||
</td>
|
||||
<td width="30%">
|
||||
<input type='hidden' id="notify_allow_default_outbound_hidden_input" name='notify_allow_default_outbound' value='0'>
|
||||
<input id="notify_allow_default_outbound" name='notify_allow_default_outbound' value="2" tabindex='1' class="checkbox" type="checkbox" {$notify_allow_default_outbound_on}>
|
||||
<input id="notify_allow_default_outbound" name='notify_allow_default_outbound' value="2" tabindex='1' class="checkbox" type="checkbox" style="margin-top: 10px;" {$notify_allow_default_outbound_on}>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="legacy-compose-option" {if isset($legacyEmailConfigEnabled)}style="display:none"{/if}>
|
||||
|
@ -216,13 +159,6 @@ function change_state(radiobutton) {
|
|||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan="4"> </tr>
|
||||
<tr>
|
||||
<td width="15%"><input type="button" class="btn btn-info" value="{$APP.LBL_EMAIL_TEST_OUTBOUND_SETTINGS}" onclick="testOutboundSettings();"> </td>
|
||||
<td width="15%"> </td>
|
||||
<td width="40%"> </td>
|
||||
<td width="40%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -182,8 +182,12 @@ class ViewConfig extends SugarView
|
|||
LoggerManager::getLogger()->warn('EmailMan view display error: mail allow user send is not set for focus');
|
||||
}
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemEmail();
|
||||
|
||||
$this->ss->assign("system_outbound_email_id", $oe->id);
|
||||
$this->ss->assign("system_outbound_email_name", $oe->name);
|
||||
|
||||
$this->ss->assign("mail_smtptype", $mailSmtpType);
|
||||
$this->ss->assign("mail_smtpserver", $mailSmtpServer);
|
||||
$this->ss->assign("mail_smtpport", $mailSmtpPort);
|
||||
$this->ss->assign("mail_smtpuser", $mailSmtpUser);
|
||||
|
@ -277,7 +281,7 @@ class ViewConfig extends SugarView
|
|||
$sugar_config['email_xss'] = getDefaultXssTags();
|
||||
}
|
||||
|
||||
foreach (unserialize(base64_decode($sugar_config['email_xss'])) as $k => $v) {
|
||||
foreach (unserialize(base64_decode($sugar_config['email_xss']), ['allowed_classes' => false]) as $k => $v) {
|
||||
$this->ss->assign($k."Checked", 'CHECKED');
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ if (!$focus->ACLAccess('Delete')) {
|
|||
$focus->mark_deleted($_REQUEST['record']);
|
||||
|
||||
if (isset($_REQUEST['record'])) {
|
||||
$query = "DELETE FROM emailman WHERE marketing_id ='" . $_REQUEST['record'] ."'";
|
||||
$query = "DELETE FROM emailman WHERE marketing_id ='" . $focus->db->quote($_REQUEST['record']) ."'";
|
||||
$focus->db->query($query);
|
||||
}
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ class EmailTemplate extends SugarBean
|
|||
|
||||
public function fill_in_additional_detail_fields()
|
||||
{
|
||||
if (empty($this->body) && !empty($this->body_html)) {
|
||||
if (!empty($this->body_html)) {
|
||||
global $sugar_config;
|
||||
|
||||
$bodyCleanup = $this->body_html;
|
||||
|
|
|
@ -812,7 +812,9 @@ class Email extends Basic
|
|||
$fromaddress,
|
||||
$toaddress,
|
||||
$mail_sendtype = 'smtp',
|
||||
$fromname = ''
|
||||
$fromname = '',
|
||||
$authType = 'no_auth',
|
||||
$externalOAuthConnectionId = ''
|
||||
) {
|
||||
global $current_user, $app_strings;
|
||||
$mod_strings = return_module_language($GLOBALS['current_language'], 'Emails'); //Called from EmailMan as well.
|
||||
|
@ -821,22 +823,14 @@ class Email extends Basic
|
|||
if ($mail->Mailer == 'smtp') {
|
||||
$mail->Host = $mailserver_url;
|
||||
$mail->Port = $port;
|
||||
if (isset($ssltls) && !empty($ssltls)) {
|
||||
$mail->protocol = "ssl://";
|
||||
if ($ssltls == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($ssltls == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} // if
|
||||
} else {
|
||||
$mail->protocol = "tcp://";
|
||||
}
|
||||
if ($smtp_auth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $smtp_username;
|
||||
$mail->Password = $smtppassword;
|
||||
}
|
||||
|
||||
$mail->setSecureProtocol($ssltls ?? false);
|
||||
$mail->initSMTPAuth(
|
||||
$authType ?? '',
|
||||
$externalOAuthConnectionId ?? '',
|
||||
$smtp_username ?? '',
|
||||
$smtppassword ?? ''
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = 'sendmail';
|
||||
}
|
||||
|
@ -2789,18 +2783,14 @@ class Email extends Basic
|
|||
$mail->Mailer = "smtp";
|
||||
$mail->Host = $oe->mail_smtpserver;
|
||||
$mail->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} // if
|
||||
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $oe->mail_smtpuser;
|
||||
$mail->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$mail->setSecureProtocol($oe->mail_smtpssl);
|
||||
$mail->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = "sendmail";
|
||||
}
|
||||
|
@ -2842,18 +2832,14 @@ class Email extends Basic
|
|||
$mail->Mailer = "smtp";
|
||||
$mail->Host = $oe->mail_smtpserver;
|
||||
$mail->Port = $oe->mail_smtpport;
|
||||
if ($oe->mail_smtpssl == 1) {
|
||||
$mail->SMTPSecure = 'ssl';
|
||||
} // if
|
||||
if ($oe->mail_smtpssl == 2) {
|
||||
$mail->SMTPSecure = 'tls';
|
||||
} // if
|
||||
|
||||
if ($oe->mail_smtpauth_req) {
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $oe->mail_smtpuser;
|
||||
$mail->Password = $oe->mail_smtppass;
|
||||
}
|
||||
$mail->setSecureProtocol($oe->mail_smtpssl);
|
||||
$mail->initSMTPAuth(
|
||||
$oe->auth_type ?? '',
|
||||
$oe->external_oauth_connection_id ?? '',
|
||||
$oe->mail_smtpuser ?? '',
|
||||
$oe->mail_smtppass ?? '',
|
||||
);
|
||||
} else {
|
||||
$mail->Mailer = "sendmail";
|
||||
}
|
||||
|
@ -3295,15 +3281,12 @@ class Email extends Basic
|
|||
*/
|
||||
public function getSystemDefaultEmail()
|
||||
{
|
||||
$email = array();
|
||||
|
||||
$r1 = $this->db->query('SELECT config.value FROM config WHERE name=\'fromaddress\'');
|
||||
$r2 = $this->db->query('SELECT config.value FROM config WHERE name=\'fromname\'');
|
||||
$a1 = $this->db->fetchByAssoc($r1);
|
||||
$a2 = $this->db->fetchByAssoc($r2);
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemMailerSettings();
|
||||
|
||||
$email['email'] = $a1['value'];
|
||||
$email['name'] = $a2['value'];
|
||||
$email['email'] = $oe->smtp_from_addr ?? '';
|
||||
$email['name'] = $oe->smtp_from_name ?? '';
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
@ -3419,7 +3402,7 @@ class Email extends Basic
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (empty($this->contact_id) && !empty($this->parent_id) && !empty($this->parent_type) && $this->parent_type === 'Contacts' && !empty($this->parent_name)) {
|
||||
$this->contact_id = $this->parent_id;
|
||||
$this->contact_name = $this->parent_name;
|
||||
|
@ -4438,14 +4421,16 @@ eoq;
|
|||
|
||||
// is from address in the request?
|
||||
|
||||
if (!isset($request['from_addr_name']) || !$request['from_addr_name']) {
|
||||
$useDefaultFromAddressName = true;
|
||||
}
|
||||
if (!isset($request['from_addr'])) {
|
||||
if (!isset($request['from_addr_name']) || !$request['from_addr_name']) {
|
||||
$useDefaultFromAddressName = true;
|
||||
}
|
||||
|
||||
// is from name in the request?
|
||||
// is from name in the request?
|
||||
|
||||
if (!isset($request['from_addr_email']) || !$request['from_addr_email']) {
|
||||
$useDefaultFromAddressEmail = true;
|
||||
if (!isset($request['from_addr_email']) || !$request['from_addr_email']) {
|
||||
$useDefaultFromAddressEmail = true;
|
||||
}
|
||||
}
|
||||
|
||||
// so, do we have to use any default data?
|
||||
|
|
|
@ -1561,7 +1561,7 @@ HTML;
|
|||
}
|
||||
if (file_exists($cache)) {
|
||||
include($cache); // profides $cacheFile
|
||||
$metaOut = unserialize($cacheFile['out']);
|
||||
$metaOut = unserialize($cacheFile['out'], ['allowed_classes' => false]);
|
||||
$meta = $metaOut['meta']['email'];
|
||||
if (isset($meta['attachments'])) {
|
||||
$attachmentHtmlData = $meta['attachments'];
|
||||
|
@ -3391,9 +3391,7 @@ eoq;
|
|||
include($cacheFilePath); // provides $cacheFile
|
||||
|
||||
if (isset($cacheFile[$key])) {
|
||||
$ret = unserialize($cacheFile[$key]);
|
||||
|
||||
return $ret;
|
||||
return unserialize($cacheFile[$key], ['allowed_classes' => false]);
|
||||
}
|
||||
} else {
|
||||
$GLOBALS['log']->debug("EMAILUI: cache file not found [ {$cacheFilePath} ] - creating blank cache file");
|
||||
|
|
|
@ -1510,7 +1510,7 @@ eoq;
|
|||
|
||||
foreach ($ie->field_defs as $k => $v) {
|
||||
if ($k == 'stored_options') {
|
||||
$ie->$k = unserialize(base64_decode($ie->$k));
|
||||
$ie->$k = unserialize(base64_decode($ie->$k), ['allowed_classes' => false]);
|
||||
if (isset($ie->stored_options['from_name'])) {
|
||||
$ie->stored_options['from_name'] = from_html($ie->stored_options['from_name']);
|
||||
}
|
||||
|
|
|
@ -498,7 +498,7 @@ class ListViewDataEmails extends ListViewData
|
|||
$ret = $emailHeader['flagged'];
|
||||
break;
|
||||
case 'name':
|
||||
$ret = html_entity_decode((string) $inboundEmail->handleMimeHeaderDecode($emailHeader['subject'] ?? ''));
|
||||
$ret = html_entity_decode(purify_html((string) $inboundEmail->handleMimeHeaderDecode($emailHeader['subject'] ?? '')));
|
||||
break;
|
||||
case 'date_entered':
|
||||
$db = DBManagerFactory::getInstance();
|
||||
|
|
|
@ -42,6 +42,7 @@ if (!defined('sugarEntry') || !sugarEntry) {
|
|||
die('Not A Valid Entry Point');
|
||||
}
|
||||
|
||||
use League\OAuth2\Client\Provider\AbstractProvider;
|
||||
use League\OAuth2\Client\Token\AccessTokenInterface;
|
||||
|
||||
interface ExternalOAuthProviderConnectorInterface
|
||||
|
@ -142,4 +143,12 @@ interface ExternalOAuthProviderConnectorInterface
|
|||
* @return string
|
||||
*/
|
||||
public function getAccessTokenRequestGrant(array $providerConfig): string;
|
||||
|
||||
/**
|
||||
* Get Provider
|
||||
* @param string $requestClientId
|
||||
* @param string $requestClientSecret
|
||||
* @return AbstractProvider|null
|
||||
*/
|
||||
public function getProvider(string $requestClientId, string $requestClientSecret): ?AbstractProvider;
|
||||
}
|
||||
|
|
|
@ -268,6 +268,59 @@ class OAuthAuthorizationService
|
|||
];
|
||||
}
|
||||
|
||||
public function refreshExpiredOAuthToken(string $oAuthConnectionId): void
|
||||
{
|
||||
/** @var ExternalOAuthConnection $oauthConnection */
|
||||
$oauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $oAuthConnectionId);
|
||||
|
||||
$hasExpiredFeedback = $this->hasConnectionTokenExpired($oauthConnection);
|
||||
$refreshToken = $hasExpiredFeedback['refreshToken'] ?? false;
|
||||
if ($refreshToken === true) {
|
||||
$refreshTokenFeedback = $this->refreshConnectionToken($oauthConnection);
|
||||
|
||||
if ($refreshTokenFeedback['success'] === false) {
|
||||
$message = $this->getOAuthRefreshTokenErrorMessage(
|
||||
$refreshTokenFeedback['reLogin'],
|
||||
$oauthConnection,
|
||||
$oAuthConnectionId
|
||||
);
|
||||
displayAdminError($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refersh token error messages
|
||||
* @param $reLogin
|
||||
* @param ExternalOAuthConnection $oauthConnection
|
||||
* @param string $oAuthConnectionId
|
||||
* @return string
|
||||
*/
|
||||
public function getOAuthRefreshTokenErrorMessage(
|
||||
$reLogin,
|
||||
ExternalOAuthConnection $oauthConnection,
|
||||
string $oAuthConnectionId
|
||||
): string {
|
||||
$message = translate('ERR_OAUTH_CONNECTION_ERROR');
|
||||
$linkAction = 'DetailView';
|
||||
|
||||
if ($reLogin === true) {
|
||||
$linkAction = 'EditView';
|
||||
$message = translate('WARN_OAUTH_TOKEN_SESSION_EXPIRED');
|
||||
}
|
||||
|
||||
$oauthConnectionName = $oauthConnection->name;
|
||||
|
||||
$hasAccess = $oauthConnection->ACLAccess('edit') ?? false;
|
||||
if ($hasAccess === true) {
|
||||
$message .= " <a href=\"index.php?module=ExternalOAuthConnection&action=$linkAction&record=$oAuthConnectionId\">$oauthConnectionName</a>.";
|
||||
} else {
|
||||
$message .= $oauthConnectionName . '.';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map token to bean fields array
|
||||
* @param string $providerId
|
||||
|
|
|
@ -73,6 +73,7 @@ class ExternalOAuthProvider extends Basic
|
|||
public $expires_in_mapping;
|
||||
public $refresh_token_mapping;
|
||||
public $token_type_mapping;
|
||||
public $redirect_uri_type;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -322,10 +323,13 @@ class ExternalOAuthProvider extends Basic
|
|||
global $sugar_config;
|
||||
|
||||
$siteUrl = $sugar_config['site_url'] ?? '';
|
||||
|
||||
$siteUrl = str_ireplace('index.php', '', (string) $siteUrl);
|
||||
$siteUrl = rtrim($siteUrl, " \t\n\r\0\x0B\/");
|
||||
|
||||
if ($this->redirect_uri_type === 'pretty_url') {
|
||||
return $siteUrl . '/ep/setExternalOAuthToken';
|
||||
}
|
||||
|
||||
return $siteUrl . '/index.php?entryPoint=setExternalOAuthToken';
|
||||
}
|
||||
|
||||
|
|
196
modules/ExternalOAuthProvider/js/fields.js
Normal file
196
modules/ExternalOAuthProvider/js/fields.js
Normal file
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM 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 SUITECRM, SUITECRM 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/>.
|
||||
*
|
||||
* 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
|
||||
* "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 "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
var externalOAuthProviderFields = function () {
|
||||
|
||||
var getDefaultFieldGetter = function () {
|
||||
return function (field$) {
|
||||
return (field$ && field$.val()) || '';
|
||||
};
|
||||
};
|
||||
|
||||
var getFunctionFieldGetter = function () {
|
||||
return function (field$) {
|
||||
field$ = field$[0];
|
||||
if (!field$) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return field$.innerText || field$.textContent || '';
|
||||
};
|
||||
};
|
||||
|
||||
var getDefaultFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.val(value);
|
||||
field$.change();
|
||||
};
|
||||
};
|
||||
|
||||
var getFunctionFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
field$ = field$[0];
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.innerText = value || '';
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
fields: {
|
||||
'record': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'name': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'client_id': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'client_secret': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'redirect_uri_span': {
|
||||
type: 'function'
|
||||
},
|
||||
'redirect_uri_type': {
|
||||
type: 'enum'
|
||||
},
|
||||
},
|
||||
|
||||
getters: {
|
||||
default: getDefaultFieldGetter(),
|
||||
varchar: getDefaultFieldGetter(),
|
||||
function: getFunctionFieldGetter(),
|
||||
checkbox: function (field$) {
|
||||
return (field$ && field$.prop('checked')) || false;
|
||||
}
|
||||
},
|
||||
|
||||
setters: {
|
||||
default: getDefaultFieldSetter(),
|
||||
varchar: getDefaultFieldSetter(),
|
||||
function: getFunctionFieldSetter(),
|
||||
checkbox: function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.prop('checked', !!value);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function (field, value) {
|
||||
var field$ = this.getField$(field);
|
||||
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var setter = this.getValueSetter(field);
|
||||
if (!setter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return setter(field$, value);
|
||||
},
|
||||
|
||||
getValue: function (field) {
|
||||
var field$ = this.getField$(field);
|
||||
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var getter = this.getValueGetter(field);
|
||||
|
||||
if (!getter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getter(field$);
|
||||
},
|
||||
|
||||
hide: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.hide();
|
||||
},
|
||||
|
||||
show: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.show();
|
||||
},
|
||||
|
||||
|
||||
getField$: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].getField$) || null;
|
||||
|
||||
if (handler) {
|
||||
return handler(field);
|
||||
}
|
||||
|
||||
return $('#' + field) || null;
|
||||
},
|
||||
|
||||
getFieldCell$: function (field) {
|
||||
return $('[data-field="' + field + '"]') || null;
|
||||
},
|
||||
|
||||
getFieldType: function (field) {
|
||||
return (this.fields[field] && this.fields[field].type) || 'varchar';
|
||||
},
|
||||
|
||||
getValueGetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.getters[type] || this.getters['default'];
|
||||
},
|
||||
|
||||
getValueSetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.setters[type] || this.setters['default'];
|
||||
}
|
||||
|
||||
};
|
||||
}();
|
57
modules/ExternalOAuthProvider/js/redirect_uri_toggle.js
Normal file
57
modules/ExternalOAuthProvider/js/redirect_uri_toggle.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM 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 SUITECRM, SUITECRM 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/>.
|
||||
*
|
||||
* 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
|
||||
* "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 "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
function toggleRedirectUri(type, url) {
|
||||
var fieldValues = {
|
||||
'query_string': {
|
||||
'uri': 'index.php?entryPoint=setExternalOAuthToken'
|
||||
},
|
||||
'pretty_url': {
|
||||
'uri': 'ep/setExternalOAuthToken'
|
||||
}
|
||||
}
|
||||
|
||||
var match = url.match(/^(.*?)(?:index\.php|ep)(?:\/|\?|$)/);
|
||||
match = match ? match[1] : url;
|
||||
|
||||
var uri = fieldValues[type] ? fieldValues[type].uri : '';
|
||||
|
||||
externalOAuthProviderFields.setValue('redirect_uri_span', match + uri);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
var url = externalOAuthProviderFields.getValue('redirect_uri_span');
|
||||
var type = externalOAuthProviderFields.getValue('redirect_uri_type');
|
||||
toggleRedirectUri(type, url);
|
||||
|
||||
|
||||
externalOAuthProviderFields.getField$('redirect_uri_type').change(function () {
|
||||
url = externalOAuthProviderFields.getValue('redirect_uri_span');
|
||||
type = externalOAuthProviderFields.getValue('redirect_uri_type');
|
||||
toggleRedirectUri(type, url);
|
||||
});
|
||||
});
|
|
@ -76,6 +76,7 @@ $mod_strings = [
|
|||
'LBL_TYPE' => 'Type',
|
||||
'LBL_CONNECTOR' => 'Connector',
|
||||
'LBL_REDIRECT_URI' => 'Redirect URI',
|
||||
'LBL_REDIRECT_URI_TYPE' => 'Redirect URI Type',
|
||||
|
||||
'LBL_CLIENT_ID' => 'Client Id',
|
||||
'LBL_CLIENT_SECRET' => 'Client Secret',
|
||||
|
|
|
@ -95,7 +95,7 @@ $viewdefs[$module_name]['DetailView'] = [
|
|||
],
|
||||
[
|
||||
'redirect_uri',
|
||||
''
|
||||
'redirect_uri_type'
|
||||
],
|
||||
],
|
||||
'lbl_extra' => [
|
||||
|
|
|
@ -68,6 +68,13 @@ $viewdefs['ExternalOAuthProvider'] = [
|
|||
'panelDefault' => 'expanded',
|
||||
],
|
||||
],
|
||||
'javascript' => '
|
||||
<script type="text/javascript">
|
||||
{suite_combinescripts
|
||||
files="modules/ExternalOAuthProvider/js/fields.js,
|
||||
modules/ExternalOAuthProvider/js/redirect_uri_toggle.js"}
|
||||
</script>
|
||||
'
|
||||
],
|
||||
'panels' => [
|
||||
'default' => [
|
||||
|
@ -93,7 +100,7 @@ $viewdefs['ExternalOAuthProvider'] = [
|
|||
],
|
||||
[
|
||||
'redirect_uri',
|
||||
''
|
||||
'redirect_uri_type'
|
||||
],
|
||||
],
|
||||
'lbl_extra' => [
|
||||
|
|
|
@ -127,6 +127,21 @@ $dictionary['ExternalOAuthProvider'] = [
|
|||
'exportable' => false,
|
||||
'unified_search' => false,
|
||||
],
|
||||
'redirect_uri_type' => [
|
||||
'name' => 'redirect_uri_type',
|
||||
'vname' => 'LBL_REDIRECT_URI_TYPE',
|
||||
'type' => 'enum',
|
||||
'default' => 'pretty_url',
|
||||
'options' => 'redirect_uri_type_dom',
|
||||
'len' => 50,
|
||||
'required' => false,
|
||||
'reportable' => false,
|
||||
'massupdate' => false,
|
||||
'inline_edit' => false,
|
||||
'importable' => false,
|
||||
'exportable' => false,
|
||||
'unified_search' => false,
|
||||
],
|
||||
'client_id' => [
|
||||
'name' => 'client_id',
|
||||
'vname' => 'LBL_CLIENT_ID',
|
||||
|
@ -185,6 +200,7 @@ $dictionary['ExternalOAuthProvider'] = [
|
|||
'vname' => 'LBL_AUTHORIZE_URL_OPTIONS',
|
||||
'type' => 'stringmap',
|
||||
'dbType' => 'text',
|
||||
'default' => '{"prompt":"login"}',
|
||||
'show_keys' => true,
|
||||
'required' => false,
|
||||
'reportable' => false,
|
||||
|
|
|
@ -52,7 +52,7 @@ require_once('modules/Import/ImportDuplicateCheck.php');
|
|||
class Importer
|
||||
{
|
||||
/**
|
||||
* @var ImportFieldSanitizer
|
||||
* @var ImportFieldSanitize
|
||||
*/
|
||||
protected $ifs;
|
||||
|
||||
|
@ -62,27 +62,27 @@ class Importer
|
|||
protected $defaultUserCurrency;
|
||||
|
||||
/**
|
||||
* @var importColumns
|
||||
* @var array
|
||||
*/
|
||||
protected $importColumns;
|
||||
|
||||
/**
|
||||
* @var importSource
|
||||
* @var ImportDataSource
|
||||
*/
|
||||
protected $importSource;
|
||||
|
||||
/**
|
||||
* @var $isUpdateOnly
|
||||
* @var bool
|
||||
*/
|
||||
protected $isUpdateOnly;
|
||||
|
||||
/**
|
||||
* @var $bean
|
||||
* @var SugarBean
|
||||
*/
|
||||
protected $bean;
|
||||
|
||||
/**
|
||||
* @var sugarToExternalSourceFieldMap
|
||||
* @var array
|
||||
*/
|
||||
protected $sugarToExternalSourceFieldMap = array();
|
||||
|
||||
|
@ -97,7 +97,7 @@ class Importer
|
|||
$this->bean = $bean;
|
||||
|
||||
// use our own error handler
|
||||
set_error_handler(array('Importer','handleImportErrors'), E_ALL);
|
||||
set_error_handler(array('Importer','handleImportErrors'), E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_WARNING & ~E_NOTICE);
|
||||
|
||||
// Increase the max_execution_time since this step can take awhile
|
||||
ini_set("max_execution_time", max($sugar_config['import_max_execution_time'], 3600));
|
||||
|
|
|
@ -130,7 +130,7 @@ abstract class ImportDataSource implements Iterator
|
|||
* @return void
|
||||
*/
|
||||
abstract public function getHeaderColumns();
|
||||
|
||||
|
||||
/**
|
||||
* Set the source name.
|
||||
*
|
||||
|
@ -197,7 +197,7 @@ abstract class ImportDataSource implements Iterator
|
|||
if ($module == 'Case') {
|
||||
$module = 'aCase';
|
||||
}
|
||||
|
||||
|
||||
$last_import->bean_type = $module;
|
||||
$last_import->bean_id = $id;
|
||||
return $last_import->save();
|
||||
|
@ -228,9 +228,9 @@ abstract class ImportDataSource implements Iterator
|
|||
{
|
||||
global $current_language;
|
||||
$mod_strings = return_module_language($current_language, 'Import');
|
||||
return "<b>{$mod_strings['LBL_ERROR']}</b> $error <br/>".
|
||||
"<b>{$mod_strings['LBL_FIELD_NAME']}</b> $fieldName <br/>" .
|
||||
"<b>{$mod_strings['LBL_VALUE']}</b> $fieldValue <br/>";
|
||||
return "{$mod_strings['LBL_ERROR']}: $error. ".
|
||||
"- {$mod_strings['LBL_FIELD_NAME']}: $fieldName. " .
|
||||
"- {$mod_strings['LBL_VALUE']}: $fieldValue";
|
||||
}
|
||||
public function resetRowErrorCounter()
|
||||
{
|
||||
|
@ -330,7 +330,7 @@ abstract class ImportDataSource implements Iterator
|
|||
//Add the error message to the first column
|
||||
array_unshift($rowData, $errorMessage);
|
||||
fputcsv($fp, $rowData);
|
||||
|
||||
|
||||
fclose($fp);
|
||||
fclose($fpNoErrors);
|
||||
}
|
||||
|
|
|
@ -47,12 +47,11 @@
|
|||
{
|
||||
padding-left: 0px;
|
||||
}
|
||||
div.resultsTable {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
padding-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
div.resultsTable {
|
||||
overflow: auto;
|
||||
padding-top: 20px;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
{/literal}
|
||||
|
||||
|
@ -98,7 +97,7 @@
|
|||
</form>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
<table width="100%" id="tabListContainerTable" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td nowrap id="tabListContainerTD">
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
{counter start=0 name="colCounter" print=false assign="colCounter"}
|
||||
{foreach from=$rowData key=col item=params}
|
||||
{strip}
|
||||
<td align='left' valign="top">
|
||||
<td align='left' valign="top" scope="record">
|
||||
{$params}
|
||||
</td>
|
||||
{/strip}
|
||||
|
|
|
@ -128,7 +128,7 @@ class ImportListView
|
|||
$this->ss->assign('navStrings', $navStrings);
|
||||
$this->ss->assign('pageData', $this->generatePaginationData());
|
||||
$this->ss->assign('tableID', $this->tableID);
|
||||
$this->ss->assign('colCount', count($this->headerColumns));
|
||||
$this->ss->assign('colCount', is_countable($this->headerColumns) ? count($this->headerColumns) : 0);
|
||||
$this->ss->assign('APP', $app_strings);
|
||||
$this->ss->assign('rowColor', array('oddListRow', 'evenListRow'));
|
||||
$this->ss->assign('displayColumns', $this->headerColumns);
|
||||
|
|
|
@ -215,7 +215,7 @@ ProcessImport = new function()
|
|||
+ "&import_module={$_REQUEST['import_module']}"
|
||||
+ "&has_header=" + document.getElementById("importstepdup").has_header.value ;
|
||||
if ( ProcessImport.fileCount >= ProcessImport.fileTotal ) {
|
||||
YAHOO.SUGAR.MessageBox.updateProgress(1,'{$mod_strings['LBL_IMPORT_COMPLETED']}');
|
||||
YAHOO.SUGAR.MessageBox.updateProgress(100,'{$mod_strings['LBL_IMPORT_COMPLETED']}');
|
||||
SUGAR.util.hrefURL(locationStr);
|
||||
}
|
||||
else {
|
||||
|
@ -238,7 +238,7 @@ ProcessImport = new function()
|
|||
);
|
||||
var move = 0;
|
||||
if ( this.fileTotal > 0 ) {
|
||||
move = this.fileCount/this.fileTotal;
|
||||
move = (this.fileCount/this.fileTotal) * 100;
|
||||
}
|
||||
YAHOO.SUGAR.MessageBox.updateProgress( move,
|
||||
"{$mod_strings['LBL_IMPORT_RECORDS']} " + ((this.fileCount * this.recordThreshold) + 1)
|
||||
|
|
|
@ -150,7 +150,7 @@ class AOPInboundEmail extends InboundEmail
|
|||
$GLOBALS['log']->debug('InboundEmail created one case with number: '.$c->case_number);
|
||||
$createCaseTemplateId = $this->get_stored_options('create_case_email_template', "");
|
||||
if (!empty($this->stored_options)) {
|
||||
$storedOptions = unserialize(base64_decode($this->stored_options));
|
||||
$storedOptions = unserialize(base64_decode($this->stored_options), ['allowed_classes' => false]);
|
||||
}
|
||||
if (!empty($createCaseTemplateId)) {
|
||||
$fromName = "";
|
||||
|
|
|
@ -1572,7 +1572,7 @@ class InboundEmail extends SugarBean
|
|||
flush();
|
||||
} // while
|
||||
fclose($fh);
|
||||
$diff = unserialize($data);
|
||||
$diff = unserialize($data, ['allowed_classes' => false]);
|
||||
if (!empty($diff)) {
|
||||
if ((is_countable($diff) ? count($diff) : 0) > 50) {
|
||||
$newDiff = array_slice($diff, 50, is_countable($diff) ? count($diff) : 0, true);
|
||||
|
@ -2035,7 +2035,7 @@ class InboundEmail extends SugarBean
|
|||
flush();
|
||||
} // while
|
||||
fclose($fh);
|
||||
$results = unserialize($data);
|
||||
$results = unserialize($data, ['allowed_classes' => false]);
|
||||
} // if
|
||||
} // if
|
||||
if (!$cacheDataExists) {
|
||||
|
@ -2964,7 +2964,7 @@ class InboundEmail extends SugarBean
|
|||
|
||||
$focusUser = BeanFactory::newBean('Users');
|
||||
$focusUser->retrieve($groupId);
|
||||
$mailerId = (isset($_REQUEST['outbound_email'])) ? $_REQUEST['outbound_email'] : "";
|
||||
$mailerId = (isset($_REQUEST['outbound_email'])) ? $this->db->quote($_REQUEST['outbound_email']) : "";
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
if ($mailerId != "") {
|
||||
|
@ -4144,14 +4144,14 @@ class InboundEmail extends SugarBean
|
|||
$emailMessage = $this->mailParser->parse($emailBody, false)->getTextContent();
|
||||
$emailMessage = $this->handleInlineImages($emailBody, $emailMessage);
|
||||
$emailMessage = $this->customGetMessageText($emailMessage);
|
||||
return SugarCleaner::cleanHtml($emailMessage, false);
|
||||
return html_entity_decode(purify_html(SugarCleaner::cleanHtml($emailMessage, false)));
|
||||
}
|
||||
|
||||
$emailMessage = $this->mailParser->parse($emailBody, false)->getHtmlContent();
|
||||
$emailMessage = $this->handleInlineImages($emailBody, $emailMessage);
|
||||
$emailMessage = $this->customGetMessageText($emailMessage);
|
||||
$emailMessage = $this->customGetMessageText($emailMessage) ?? '';
|
||||
|
||||
return SugarCleaner::cleanHtml($emailMessage, $clean_email);
|
||||
return html_entity_decode(purify_html(SugarCleaner::cleanHtml($emailMessage, $clean_email)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5495,7 +5495,7 @@ class InboundEmail extends SugarBean
|
|||
//// ASSIGN APPROPRIATE ATTRIBUTES TO NEW EMAIL OBJECT
|
||||
// handle UTF-8/charset encoding in the ***headers***
|
||||
|
||||
$email->name = $this->handleMimeHeaderDecode($header->subject);
|
||||
$email->name = purify_html($this->handleMimeHeaderDecode($parsedFullHeader->subject));
|
||||
$email->type = 'inbound';
|
||||
if (!empty($unixHeaderDate)) {
|
||||
$email->date_sent_received = $timedate->asUser($unixHeaderDate);
|
||||
|
@ -5713,7 +5713,7 @@ class InboundEmail extends SugarBean
|
|||
$fullHeader = $this->getImap()->fetchHeader($uid, FT_UID);
|
||||
$parsedFullHeader = $this->getImap()->rfc822ParseHeaders($fullHeader);
|
||||
|
||||
$email->name = $this->handleMimeHeaderDecode($parsedFullHeader->subject);
|
||||
$email->name = purify_html($this->handleMimeHeaderDecode($parsedFullHeader->subject));
|
||||
$email->type = 'inbound';
|
||||
|
||||
if (isset($request['metadata']['viewdefs'])) {
|
||||
|
@ -7509,7 +7509,7 @@ class InboundEmail extends SugarBean
|
|||
include($cache); // profides $cacheFile
|
||||
/** @var $cacheFile array */
|
||||
|
||||
$metaOut = unserialize($cacheFile['out']);
|
||||
$metaOut = unserialize($cacheFile['out'], ['allowed_classes' => false]);
|
||||
$meta = $metaOut['meta']['email'];
|
||||
$email = BeanFactory::newBean('Emails');
|
||||
|
||||
|
@ -8667,38 +8667,6 @@ eoq;
|
|||
return 'imap2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refersh token error messages
|
||||
* @param $reLogin
|
||||
* @param ExternalOAuthConnection $oauthConnection
|
||||
* @param string $oAuthConnectionId
|
||||
* @return string
|
||||
*/
|
||||
protected function getOAuthRefreshTokenErrorMessage(
|
||||
$reLogin,
|
||||
ExternalOAuthConnection $oauthConnection,
|
||||
string $oAuthConnectionId
|
||||
): string {
|
||||
$message = translate('ERR_IMAP_OAUTH_CONNECTION_ERROR', 'InboundEmail');
|
||||
$linkAction = 'DetailView';
|
||||
|
||||
if ($reLogin === true) {
|
||||
$linkAction = 'EditView';
|
||||
$message = translate('WARN_OAUTH_TOKEN_SESSION_EXPIRED', 'InboundEmail');
|
||||
}
|
||||
|
||||
$oauthConnectionName = $oauthConnection->name;
|
||||
|
||||
$hasAccess = $oauthConnection->ACLAccess('edit') ?? false;
|
||||
if ($hasAccess === true) {
|
||||
$message .= " <a href=\"index.php?module=ExternalOAuthConnection&action=$linkAction&record=$oAuthConnectionId\">$oauthConnectionName</a>.";
|
||||
} else {
|
||||
$message .= $oauthConnectionName . '.';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OAuthToken. Refresh if needed
|
||||
* @param string $oAuthConnectionId
|
||||
|
@ -8709,29 +8677,11 @@ eoq;
|
|||
require_once __DIR__ . '/../ExternalOAuthConnection/services/OAuthAuthorizationService.php';
|
||||
$oAuth = new OAuthAuthorizationService();
|
||||
|
||||
$oAuth->refreshExpiredOAuthToken($oAuthConnectionId);
|
||||
|
||||
/** @var ExternalOAuthConnection $oauthConnection */
|
||||
$oauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $oAuthConnectionId);
|
||||
$password = $oauthConnection->access_token;
|
||||
|
||||
$hasExpiredFeedback = $oAuth->hasConnectionTokenExpired($oauthConnection);
|
||||
$refreshToken = $hasExpiredFeedback['refreshToken'] ?? false;
|
||||
if ($refreshToken === true) {
|
||||
$refreshTokenFeedback = $oAuth->refreshConnectionToken($oauthConnection);
|
||||
|
||||
if ($refreshTokenFeedback['success'] === false) {
|
||||
$message = $this->getOAuthRefreshTokenErrorMessage(
|
||||
$refreshTokenFeedback['reLogin'],
|
||||
$oauthConnection,
|
||||
$oAuthConnectionId
|
||||
);
|
||||
displayAdminError($message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $oauthConnection->access_token;
|
||||
}
|
||||
|
||||
return $password;
|
||||
return $oauthConnection->access_token;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -167,7 +167,12 @@ if ($type === 'bounce') {
|
|||
if (!empty($_REQUEST['external_oauth_connection_id'])) {
|
||||
$externalOauthConnection = BeanFactory::getBean('ExternalOAuthConnection', $_REQUEST['external_oauth_connection_id']);
|
||||
|
||||
if ($externalOauthConnection->type !== $focus->type) {
|
||||
$focusType = $focus->type ?? '';
|
||||
if ($focusType === 'bounce') {
|
||||
$focusType = 'group';
|
||||
}
|
||||
|
||||
if ($externalOauthConnection->type !== $focusType) {
|
||||
SugarApplication::appendErrorMessage($mod_strings['LBL_TYPE_DIFFERENT']);
|
||||
SugarApplication::redirect('index.php?module=InboundEmail&action=EditView&is_personal=1&type=personal');
|
||||
return;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
function authTypetoggleFields(type) {
|
||||
function authTypeToggleFields(type) {
|
||||
|
||||
var fieldsPerType = {
|
||||
'basic': {
|
||||
|
@ -81,10 +81,10 @@ function authTypetoggleFields(type) {
|
|||
|
||||
$(document).ready(function () {
|
||||
var type = inboundEmailFields.getValue('auth_type');
|
||||
authTypetoggleFields(type);
|
||||
authTypeToggleFields(type);
|
||||
|
||||
inboundEmailFields.getField$('auth_type').change(function () {
|
||||
type = inboundEmailFields.getValue('auth_type');
|
||||
authTypetoggleFields(type);
|
||||
authTypeToggleFields(type);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ if (!defined('sugarEntry') || !sugarEntry) {
|
|||
* 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.
|
||||
* Copyright (C) 2011 - 2024 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
|
||||
|
@ -119,17 +119,19 @@ class StandardField extends DynamicField
|
|||
$this->baseField = get_widget($field->type) ;
|
||||
foreach ($field->vardef_map as $property => $fmd_col) {
|
||||
if ($property == "action" || $property == "label_value" || $property == "label"
|
||||
|| ((substr((string) $property, 0, 3) == 'ext' && strlen((string) $property) == 4))
|
||||
|| ((str_starts_with((string)$property, 'ext') && strlen((string) $property) == 4))
|
||||
// possible bug here... $property is often the same as $fmd_col, but not always. Maybe we should also add:
|
||||
// || ((str_starts_with((string)$fmd_col, 'ext') && strlen((string) $fmd_col) == 4))
|
||||
// ... but a thorough analysis of the consequences of this would be required.
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bug 37043 - Avoid writing out vardef defintions that are the default value.
|
||||
|
||||
// Avoid writing out vardef definitions that are the default value, when possible.
|
||||
// Since isDefaultvalue() is quite limited, and doesn't handle all cases well,
|
||||
// sometimes we won't detect defaults and will store them anyway.
|
||||
if (isset($newDef[$property]) &&
|
||||
(
|
||||
(!isset($currdef[$property]) && !$this->isDefaultValue($property, $newDef[$property], $this->baseField))
|
||||
|| (isset($currdef[$property]) && $currdef[$property] != $newDef[$property])
|
||||
)
|
||||
!$this->isDefaultValue($property, $newDef[$property], $this->baseField)
|
||||
) {
|
||||
$this->custom_def[$property] =
|
||||
is_string($newDef[$property]) ? htmlspecialchars_decode($newDef[$property], ENT_QUOTES) : $newDef[$property];
|
||||
|
|
|
@ -262,7 +262,7 @@ class ActivitiesRelationship extends OneToManyRelationship
|
|||
'order' => 20 ,
|
||||
'sort_order' => 'desc' ,
|
||||
'sort_by' => 'date_modified' ,
|
||||
'title_key' => 'LBL_HISTORY' ,
|
||||
'title_key' => 'LBL_HISTORY_SUBPANEL_TITLE' ,
|
||||
'type' => 'collection' ,
|
||||
'subpanel_name' => 'history' , //this values is not associated with a physical file.
|
||||
'module' => 'History' ,
|
||||
|
|
|
@ -463,7 +463,7 @@ abstract class AbstractMetaDataImplementation
|
|||
// BEGIN ASSERTIONS
|
||||
if ($type != MB_BASEMETADATALOCATION && $type != MB_HISTORYMETADATALOCATION) {
|
||||
// just warn rather than die
|
||||
$GLOBALS ['log']->warning(
|
||||
$GLOBALS ['log']->warn(
|
||||
"UndeployedMetaDataImplementation->getFileName(): view type $type is not recognized"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -78,8 +78,7 @@ class TabController
|
|||
$trimmed_tabs = trim($tabs);
|
||||
//make sure serialized string is not empty
|
||||
if (!empty($trimmed_tabs)) {
|
||||
$tabs = base64_decode($tabs);
|
||||
$tabs = unserialize($tabs);
|
||||
$tabs = unserialize(base64_decode($tabs), ['allowed_classes' => false]);
|
||||
//Ensure modules saved in the prefences exist.
|
||||
foreach ($tabs as $id => $tab) {
|
||||
if (!in_array($tab, $moduleList)) {
|
||||
|
|
|
@ -66,6 +66,13 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
*/
|
||||
public $mail_smtpuser;
|
||||
|
||||
public $mail_smtpauth_req;
|
||||
public $mail_smtpssl;
|
||||
public $mail_smtpport;
|
||||
public $mail_smtpserver;
|
||||
public $mail_smtptype;
|
||||
public $mail_sendtype;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
@ -86,6 +93,9 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
*/
|
||||
public $reply_to_name;
|
||||
|
||||
public $auth_type = 'no_auth'; // 'no_auth', 'basic', 'oauth'
|
||||
public $external_oauth_connection_id = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
@ -113,11 +123,34 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
}
|
||||
$this->mail_smtppass = $this->mail_smtppass ? blowfishEncode(blowfishGetKey('OutBoundEmail'), $this->mail_smtppass) : null;
|
||||
|
||||
if ($this->auth_type === 'basic') {
|
||||
$this->mail_smtpauth_req = 1;
|
||||
$this->external_oauth_connection_id = '';
|
||||
}
|
||||
|
||||
if ($this->auth_type === 'no_auth') {
|
||||
$this->mail_smtppass = '';
|
||||
$this->mail_smtpauth_req = 0;
|
||||
$this->external_oauth_connection_id = '';
|
||||
}
|
||||
|
||||
if ($this->auth_type === 'oauth') {
|
||||
$this->mail_smtppass = '';
|
||||
$this->mail_smtpauth_req = 0;
|
||||
}
|
||||
|
||||
$this->smtp_from_name = trim($this->smtp_from_name);
|
||||
$this->smtp_from_addr = trim($this->smtp_from_addr);
|
||||
$this->mail_smtpserver = trim($this->mail_smtpserver);
|
||||
$this->mail_smtpuser = trim($this->mail_smtpuser);
|
||||
|
||||
if ($this->type === 'system') {
|
||||
/** @var Administration $admin */
|
||||
$admin = BeanFactory::newBean('Administration');
|
||||
$admin->saveSetting('notify', 'fromname', $this->smtp_from_name);
|
||||
$admin->saveSetting('notify', 'fromaddress', $this->smtp_from_addr);
|
||||
}
|
||||
|
||||
$results = parent::save($check_notify);
|
||||
return $results;
|
||||
}
|
||||
|
@ -134,6 +167,10 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
return null;
|
||||
}
|
||||
|
||||
if (isTrue($this->mail_smtpauth_req) && $this->auth_type === 'no_auth') {
|
||||
$this->auth_type = 'basic';
|
||||
}
|
||||
|
||||
$this->mail_smtppass = $this->mail_smtppass ? blowfishDecode(blowfishGetKey('OutBoundEmail'), $this->mail_smtppass) : null;
|
||||
return $results;
|
||||
}
|
||||
|
@ -262,7 +299,9 @@ class OutboundEmailAccounts extends OutboundEmailAccounts_sugar
|
|||
{
|
||||
global $current_user;
|
||||
|
||||
$isNotAllowAction = $this->isNotAllowedAction($view);
|
||||
$view = $view ?? '';
|
||||
|
||||
$isNotAllowAction = $this->isNotAllowedAction($view ?? '');
|
||||
if ($isNotAllowAction === true) {
|
||||
return false;
|
||||
}
|
||||
|
@ -406,6 +445,7 @@ HTML;
|
|||
$adminNotifyFromAddress = $admin->settings['notify_fromaddress'];
|
||||
isValidEmailAddress($adminNotifyFromAddress);
|
||||
$adminNotifyFromName = $admin->settings['notify_fromname'];
|
||||
$record = $_REQUEST['record'] ?? '';
|
||||
$html = <<<HTML
|
||||
<input id="sendTestOutboundEmailSettingsBtn" type="button" class="button" value="{$APP['LBL_EMAIL_TEST_OUTBOUND_SETTINGS']}" onclick="testOutboundSettings();">
|
||||
<script type="text/javascript" src="cache/include/javascript/sugar_grp_yui_widgets.js"></script>
|
||||
|
@ -431,6 +471,15 @@ HTML;
|
|||
};
|
||||
|
||||
function testOutboundSettingsDialog() {
|
||||
|
||||
var notifyFromAddress = document.getElementById('smtp_from_addr') && document.getElementById('smtp_from_addr').value;
|
||||
var notifyFromName = document.getElementById('smtp_from_name') && document.getElementById('smtp_from_name').value;
|
||||
|
||||
if (!notifyFromAddress || !notifyFromName) {
|
||||
overlay("{$APP['ERR_INVALID_REQUIRED_FIELDS']}", "{$APP['LBL_EMAIL_SETTINGS_FROM_ADDR_NOT_SET']}", 'alert');
|
||||
return;
|
||||
}
|
||||
|
||||
// lazy load dialogue
|
||||
if(!EmailMan.testOutboundDialog) {
|
||||
EmailMan.testOutboundDialog = new YAHOO.widget.Dialog("testOutboundDialog", {
|
||||
|
@ -507,7 +556,9 @@ HTML;
|
|||
var smtpServer = document.getElementById('mail_smtpserver').value;
|
||||
var smtpPort = document.getElementById('mail_smtpport').value;
|
||||
var smtpssl = document.getElementById('mail_smtpssl').value;
|
||||
var mailsmtpauthreq = document.getElementById('mail_smtpauth_req');
|
||||
var authType = document.getElementById('auth_type').value || 'no_auth';
|
||||
var externalOauthConnectionId = document.getElementById('external_oauth_connection_id').value || '';
|
||||
var smtpPass = trim(document.getElementById('mail_smtppass').value);
|
||||
var mail_sendtype = 'SMTP';
|
||||
var adminNotifyFromAddress = document.getElementById('smtp_from_addr').value ? document.getElementById('smtp_from_addr').value :'$adminNotifyFromName';
|
||||
var adminNotifyFromName = document.getElementById('smtp_from_name').value ? document.getElementById('smtp_from_name').value : '$adminNotifyFromAddress';
|
||||
|
@ -516,9 +567,12 @@ HTML;
|
|||
'mail_sendtype=' + mail_sendtype + '&' +
|
||||
'mail_smtpserver=' + smtpServer + "&" +
|
||||
"mail_smtpport=" + smtpPort + "&mail_smtpssl=" + smtpssl + "&" +
|
||||
"mail_smtpauth_req=" + mailsmtpauthreq.checked + "&" +
|
||||
"mail_auth_type=" + authType + "&" +
|
||||
"mail_external_oauth_connection_id=" + externalOauthConnectionId + "&" +
|
||||
"mail_smtpauth_req=" + (authType === 'basic' ? 1 : 0) + "&" +
|
||||
"mail_smtpuser=" + trim(document.getElementById('mail_smtpuser').value) + "&" +
|
||||
"mail_smtppass=" + trim(document.getElementById('mail_smtppass').value) + "&" +
|
||||
"mail_smtppass=" + smtpPass + "&" +
|
||||
"record=" + '$record' + "&" +
|
||||
"outboundtest_to_address=" + toAddress + '&' +
|
||||
'outboundtest_from_address=' + adminNotifyFromAddress + '&' +
|
||||
'mail_from_name=' + adminNotifyFromName;
|
||||
|
|
|
@ -51,6 +51,32 @@ class OutboundEmailAccountsController extends SugarController
|
|||
$this->bean->type = $type;
|
||||
}
|
||||
|
||||
if (empty($this->bean) && $type === 'system' && !is_admin($GLOBALS['current_user'])) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'noaccess';
|
||||
return;
|
||||
}
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemEmail();
|
||||
if (empty($this->bean->id) && $type === 'system' && $oe !== null) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'errors';
|
||||
$this->errors = [
|
||||
translate('LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS', 'OutboundEmailAccounts'),
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'system' && $oe !== null && $oe->id !== $this->bean->id) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'errors';
|
||||
$this->errors = [
|
||||
translate('LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS', 'OutboundEmailAccounts'),
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($_REQUEST['record']) && $type === 'user') {
|
||||
$this->hasAccess = true;
|
||||
return;
|
||||
|
@ -62,7 +88,7 @@ class OutboundEmailAccountsController extends SugarController
|
|||
}
|
||||
|
||||
public function action_save() {
|
||||
global $current_user;
|
||||
global $current_user, $mod_strings;
|
||||
$isNewRecord = (empty($this->bean->id) || $this->bean->new_with_id);
|
||||
|
||||
$this->bean->mail_sendtype = 'SMTP';
|
||||
|
@ -84,6 +110,14 @@ class OutboundEmailAccountsController extends SugarController
|
|||
}
|
||||
}
|
||||
|
||||
$oe = new OutboundEmail();
|
||||
$oe = $oe->getSystemEmail();
|
||||
$type = $this->bean->type;
|
||||
|
||||
if ($type === 'user'){
|
||||
$type = 'personal';
|
||||
}
|
||||
|
||||
if ($isNewRecord && empty($this->bean->user_id)) {
|
||||
$this->bean->user_id = $current_user->id;
|
||||
$this->bean->assigned_user_id = $current_user->id;
|
||||
|
@ -93,6 +127,34 @@ class OutboundEmailAccountsController extends SugarController
|
|||
$this->bean->assigned_user_id = $this->bean->user_id;
|
||||
}
|
||||
|
||||
$authType = $_REQUEST['auth_type'] ?? '';
|
||||
|
||||
$oauth = null;
|
||||
if ($authType === 'oauth' || ($_REQUEST['auth_type'] ?? '') === 'oauth') {
|
||||
$oauth = BeanFactory::getBean('ExternalOAuthConnection', $_REQUEST['external_oauth_connection_id']);
|
||||
}
|
||||
|
||||
if ($type === 'system' && $oe !== null && $oe->id !== $this->bean->id) {
|
||||
$this->hasAccess = false;
|
||||
$this->view = 'errors';
|
||||
$this->errors = [
|
||||
translate('LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS', 'OutboundEmailAccounts'),
|
||||
];
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === 'system' && $oauth !== null && $oauth->type !== 'group') {
|
||||
SugarApplication::appendErrorMessage($mod_strings['LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_IS_NOT_GROUP']);
|
||||
SugarApplication::redirect('index.php?module=OutboundEmailAccounts&action=DetailView&record=' . $this->bean->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type !== 'system' && $oauth !== null && $oauth->type !== $type) {
|
||||
SugarApplication::appendErrorMessage($mod_strings['LBL_ERROR_OUTBOUND_EMAIL_CONNECTION_TYPE_MISMATCH']);
|
||||
SugarApplication::redirect('index.php?module=OutboundEmailAccounts&action=DetailView&record=' . $this->bean->id);
|
||||
return;
|
||||
}
|
||||
|
||||
parent::action_save();
|
||||
}
|
||||
}
|
||||
|
|
81
modules/OutboundEmailAccounts/js/auth_type_fields_toggle.js
Normal file
81
modules/OutboundEmailAccounts/js/auth_type_fields_toggle.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* SuiteCRM is a customer relationship management program developed by SuiteCRM Ltd.
|
||||
* Copyright (C) 2025 SuiteCRM 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 SUITECRM, SUITECRM 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/>.
|
||||
*
|
||||
* 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
|
||||
* "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 "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
function authTypeToggleFields(type) {
|
||||
|
||||
var fieldsPerType = {
|
||||
'basic': {
|
||||
'mail_smtppass': true,
|
||||
'external_oauth_connection_name': false,
|
||||
},
|
||||
'no_auth': {
|
||||
'mail_smtppass': false,
|
||||
'external_oauth_connection_name': false,
|
||||
},
|
||||
'oauth': {
|
||||
'mail_smtppass': false,
|
||||
'external_oauth_connection_name': true,
|
||||
},
|
||||
};
|
||||
|
||||
var fieldType = {
|
||||
'mail_smtppass': 'password',
|
||||
'external_oauth_connection_name': 'relate',
|
||||
};
|
||||
|
||||
var fieldDisplay = fieldsPerType[type] || fieldsPerType.personal;
|
||||
|
||||
Object.keys(fieldDisplay).forEach(function (fieldKey) {
|
||||
var display = fieldDisplay[fieldKey];
|
||||
var method = 'show';
|
||||
var required = true;
|
||||
|
||||
if (!display) {
|
||||
method = 'hide';
|
||||
outboundEmailFields.setValue(fieldKey, '');
|
||||
required = false;
|
||||
}
|
||||
|
||||
var isValue = outboundEmailFields.getData(fieldKey, 'is-value-set');
|
||||
if (isValue === true) {
|
||||
required = false;
|
||||
}
|
||||
|
||||
outboundEmailFields.setRequired(fieldKey, fieldType[fieldKey], 'EditView', required);
|
||||
outboundEmailFields[method](fieldKey);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
var type = outboundEmailFields.getValue('auth_type');
|
||||
authTypeToggleFields(type);
|
||||
|
||||
outboundEmailFields.getField$('auth_type').change(function () {
|
||||
type = outboundEmailFields.getValue('auth_type');
|
||||
authTypeToggleFields(type);
|
||||
});
|
||||
});
|
|
@ -38,144 +38,256 @@
|
|||
*/
|
||||
var outboundEmailFields = function () {
|
||||
|
||||
var getDefaultFieldGetter = function () {
|
||||
return function (field$) {
|
||||
return (field$ && field$.val()) || '';
|
||||
var requiredLabelTemplate = '<span class="required">*</span>';
|
||||
var validationMessageTemplate = '<div class="required validation-message">Missing required field: $FIELD_NAME</div>';
|
||||
|
||||
var getValidationDefinition = function (formName, field) {
|
||||
if (validate[formName]) {
|
||||
for (i = 0; i < validate[formName].length; i++) {
|
||||
if (validate[formName][i][nameIndex] == field) {
|
||||
return validate[formName][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
};
|
||||
|
||||
var getDefaultFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
var configureValidation = function (formName, field, required) {
|
||||
|
||||
field$.val(value);
|
||||
field$.change();
|
||||
var definition = getValidationDefinition(formName, field);
|
||||
|
||||
if (!definition) {
|
||||
return;
|
||||
}
|
||||
var isRequired = true;
|
||||
|
||||
if (!required) {
|
||||
isRequired = false;
|
||||
}
|
||||
|
||||
definition[requiredIndex] = isRequired;
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
fields: {
|
||||
'record': {
|
||||
type: 'varchar',
|
||||
var addRequiredIndicator = function ($label) {
|
||||
var $indicator = $label.find('.required');
|
||||
|
||||
if ($indicator.length < 1) {
|
||||
$label.append($(requiredLabelTemplate));
|
||||
}
|
||||
};
|
||||
|
||||
var removeRequiredIndicator = function ($label) {
|
||||
var $indicator = $label.find('.required');
|
||||
|
||||
if ($indicator.length > 0) {
|
||||
$indicator.remove();
|
||||
}
|
||||
};
|
||||
|
||||
var getDefaultFieldGetter = function () {
|
||||
return function (field$) {
|
||||
return (field$ && field$.val()) || '';
|
||||
};
|
||||
};
|
||||
|
||||
var getDefaultFieldSetter = function () {
|
||||
return function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.val(value);
|
||||
field$.change();
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
fields: {
|
||||
'record': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'mail_smtpssl': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtppass': {
|
||||
type: 'varchar',
|
||||
},
|
||||
'owner_name': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'type': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpport': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpauth_req': {
|
||||
type: 'checkbox'
|
||||
},
|
||||
'auth_type': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'external_oauth_connection_name': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'external_oauth_connection_id': {
|
||||
type: 'varchar',
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
getters: {
|
||||
default: getDefaultFieldGetter(),
|
||||
varchar: getDefaultFieldGetter(),
|
||||
checkbox: function (field$) {
|
||||
return (field$ && field$.prop('checked')) || false;
|
||||
}
|
||||
},
|
||||
|
||||
setters: {
|
||||
default: getDefaultFieldSetter(),
|
||||
varchar: getDefaultFieldSetter(),
|
||||
checkbox: function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.prop('checked', !!value);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function (field, value) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var setter = this.getValueSetter(field);
|
||||
if (!setter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return setter(field$, value);
|
||||
},
|
||||
|
||||
getValue: function (field) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var getter = this.getValueGetter(field);
|
||||
if (!getter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getter(field$);
|
||||
},
|
||||
|
||||
getData: function (field, dataKey) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return field$.data(dataKey);
|
||||
},
|
||||
|
||||
hide: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.hide();
|
||||
},
|
||||
|
||||
show: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
field$.show();
|
||||
},
|
||||
|
||||
|
||||
getField$: function (field) {
|
||||
return $('input[name=' + field + ']') || null;
|
||||
}
|
||||
},
|
||||
'mail_smtpssl': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'owner_name': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'type': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpport': {
|
||||
type: 'varchar'
|
||||
},
|
||||
'mail_smtpauth_req': {
|
||||
type: 'checkbox'
|
||||
},
|
||||
},
|
||||
var handler = (this.fields[field] && this.fields[field].getField$) || null;
|
||||
|
||||
getters: {
|
||||
default: getDefaultFieldGetter(),
|
||||
varchar: getDefaultFieldGetter(),
|
||||
checkbox: function (field$) {
|
||||
return (field$ && field$.prop('checked')) || false;
|
||||
}
|
||||
},
|
||||
if (handler) {
|
||||
return handler(field);
|
||||
}
|
||||
|
||||
setters: {
|
||||
default: getDefaultFieldSetter(),
|
||||
varchar: getDefaultFieldSetter(),
|
||||
checkbox: function (field$, value) {
|
||||
if (!field$) {
|
||||
return;
|
||||
}
|
||||
return $('#' + field) || null;
|
||||
},
|
||||
|
||||
field$.prop('checked', !!value);
|
||||
}
|
||||
},
|
||||
getFieldCell$: function (field) {
|
||||
return $('[data-field="' + field + '"]') || null;
|
||||
},
|
||||
|
||||
setValue: function (field, value) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
getFieldType: function (field) {
|
||||
return (this.fields[field] && this.fields[field].type) || 'varchar';
|
||||
},
|
||||
|
||||
var setter = this.getValueSetter(field);
|
||||
if (!setter) {
|
||||
return null;
|
||||
}
|
||||
getValueGetter: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].getter) || null;
|
||||
|
||||
return setter(field$, value);
|
||||
},
|
||||
if (handler) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
getValue: function (field) {
|
||||
var field$ = this.getField$(field);
|
||||
if (!field$) {
|
||||
return null;
|
||||
}
|
||||
var type = this.getFieldType(field);
|
||||
return this.getters[type] || this.getters['default'];
|
||||
},
|
||||
|
||||
var getter = this.getValueGetter(field);
|
||||
if (!getter) {
|
||||
return null;
|
||||
}
|
||||
getValueSetter: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].setter) || null;
|
||||
|
||||
return getter(field$);
|
||||
},
|
||||
if (handler) {
|
||||
return handler;
|
||||
}
|
||||
|
||||
hide: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
var type = this.getFieldType(field);
|
||||
return this.setters[type] || this.setters['default'];
|
||||
},
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
setRequired: function (field, fieldType, formName, required) {
|
||||
|
||||
field$.hide();
|
||||
},
|
||||
var $editView = $('#EditView');
|
||||
if (!$editView || !$editView.length) {
|
||||
return;
|
||||
}
|
||||
configureValidation(this.formName, this.name, required);
|
||||
|
||||
show: function (field) {
|
||||
var field$ = this.getFieldCell$(field);
|
||||
this.setRequiredIndicator(field, required);
|
||||
|
||||
if (!field$ || !field$.length) {
|
||||
return;
|
||||
}
|
||||
if (required) {
|
||||
addToValidate(formName, field, fieldType, true, SUGAR.language.get('OutboundEmailAccounts', "LBL_" + field.toUpperCase()));
|
||||
} else {
|
||||
removeFromValidate(formName, field);
|
||||
}
|
||||
|
||||
field$.show();
|
||||
},
|
||||
},
|
||||
|
||||
setRequiredIndicator: function (field, required) {
|
||||
var $label = this.getFieldCell$(field).find('.label');
|
||||
if (required) {
|
||||
addRequiredIndicator($label);
|
||||
} else {
|
||||
removeRequiredIndicator($label);
|
||||
}
|
||||
},
|
||||
|
||||
getField$: function (field) {
|
||||
var handler = (this.fields[field] && this.fields[field].getField$) || null;
|
||||
|
||||
if (handler) {
|
||||
return handler(field);
|
||||
}
|
||||
|
||||
return $('#' + field) || null;
|
||||
},
|
||||
|
||||
getFieldCell$: function (field) {
|
||||
return $('[data-field="' + field + '"]') || null;
|
||||
},
|
||||
|
||||
getFieldType: function (field) {
|
||||
return (this.fields[field] && this.fields[field].type) || 'varchar';
|
||||
},
|
||||
|
||||
getValueGetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.getters[type] || this.getters['default'];
|
||||
},
|
||||
|
||||
getValueSetter: function (field) {
|
||||
var type = this.getFieldType(field);
|
||||
return this.setters[type] || this.setters['default'];
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
}();
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* 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 - 2022 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".
|
||||
*/
|
||||
function toggleAuthFields(authEnabled) {
|
||||
var status = 'disabled';
|
||||
if (authEnabled) {
|
||||
status = 'enabled';
|
||||
}
|
||||
|
||||
var fieldsPerStatus = {
|
||||
'enabled': {
|
||||
'mail_smtppass': true,
|
||||
},
|
||||
'disabled': {
|
||||
'mail_smtppass': false,
|
||||
},
|
||||
};
|
||||
|
||||
var fieldDisplay = fieldsPerStatus[status] || fieldsPerStatus.disabled;
|
||||
|
||||
Object.keys(fieldDisplay).forEach(function (fieldKey) {
|
||||
var display = fieldDisplay[fieldKey];
|
||||
var method = 'show';
|
||||
if(!display) {
|
||||
method = 'hide';
|
||||
}
|
||||
|
||||
outboundEmailFields[method](fieldKey);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
var authEnabled = outboundEmailFields.getValue('mail_smtpauth_req');
|
||||
toggleAuthFields(authEnabled);
|
||||
|
||||
$('#mail_smtpauth_req').change(function () {
|
||||
var authEnabled = outboundEmailFields.getValue('mail_smtpauth_req');
|
||||
toggleAuthFields(authEnabled);
|
||||
});
|
||||
});
|
||||
|
|
@ -118,5 +118,14 @@ $mod_strings = array(
|
|||
'LBL_OWNER' => 'Owner',
|
||||
'LBL_OWNER_NAME' => 'Owner',
|
||||
|
||||
'LNK_EXTERNAL_OAUTH_CONNECTIONS' => 'External OAuth Connections'
|
||||
'LBL_AUTH_TYPE' => 'Auth Type',
|
||||
|
||||
'LBL_EXTERNAL_OAUTH_CONNECTION' => 'External OAuth Connection',
|
||||
'LBL_EXTERNAL_OAUTH_CONNECTION_ID' => 'External OAuth Connection id',
|
||||
'LBL_EXTERNAL_OAUTH_CONNECTION_NAME' => 'External OAuth Connection',
|
||||
'LNK_EXTERNAL_OAUTH_CONNECTIONS' => 'External OAuth Connections',
|
||||
|
||||
'LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_EXISTS' => 'System Outbound Email Account already exists. Please remove it before creating a new one.',
|
||||
'LBL_ERROR_OUTBOUND_EMAIL_SYSTEM_IS_NOT_GROUP' => 'When configuring the System Outbound account using OAuth, you must select a Group-Type External Oauth Connection',
|
||||
'LBL_ERROR_OUTBOUND_EMAIL_CONNECTION_TYPE_MISMATCH' => 'When configuring the Outbound account using OAuth, you must select a External Oauth Connection the same type as the Outbound Email Account (Group or Personal)',
|
||||
);
|
||||
|
|
|
@ -37,7 +37,7 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
files="modules/OutboundEmailAccounts/js/fields.js,
|
||||
modules/OutboundEmailAccounts/js/owner_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/panel_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/smtp_auth_toggle.js"}
|
||||
modules/OutboundEmailAccounts/js/auth_type_fields_toggle.js"}
|
||||
</script>
|
||||
',
|
||||
],
|
||||
|
@ -57,17 +57,21 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
],
|
||||
'lbl_connection_configuration' => [
|
||||
[
|
||||
'mail_smtpserver',
|
||||
'mail_smtpauth_req',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
'auth_type',
|
||||
'mail_smtpuser',
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
'mail_smtpserver',
|
||||
'external_oauth_connection_name',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
'',
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
''
|
||||
],
|
||||
],
|
||||
'lbl_outbound_configuration' => [
|
||||
[
|
||||
|
|
|
@ -40,7 +40,7 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
modules/OutboundEmailAccounts/js/ssl_port_set.js,
|
||||
modules/OutboundEmailAccounts/js/panel_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/owner_toggle.js,
|
||||
modules/OutboundEmailAccounts/js/smtp_auth_toggle.js"}
|
||||
modules/OutboundEmailAccounts/js/auth_type_fields_toggle.js"}
|
||||
</script>
|
||||
',
|
||||
],
|
||||
|
@ -60,17 +60,26 @@ $viewdefs ['OutboundEmailAccounts'] = [
|
|||
],
|
||||
'lbl_connection_configuration' => [
|
||||
[
|
||||
'mail_smtpserver',
|
||||
'mail_smtpauth_req',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
'auth_type',
|
||||
'mail_smtpuser',
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
'mail_smtpserver',
|
||||
'mail_smtppass',
|
||||
],
|
||||
[
|
||||
'mail_smtpssl',
|
||||
[
|
||||
'name' => 'external_oauth_connection_name',
|
||||
'displayParams' => [
|
||||
'initial_filter' => '{if $fields.type.value === "system"}&type="+"group"+"{/if}',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'mail_smtpport',
|
||||
'',
|
||||
],
|
||||
[
|
||||
[
|
||||
'name' => 'sent_test_email_btn',
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue