SugarClub
SugarClub
  • User
  • Site
  • Search
  • User
  • Groups & Discussions
    Groups & Discussions
    • Product Forums
      Product-focused Q&A, discussions, best practices, fixes, and help
      Product Forums
      • Sugar Market
      • Sugar Sell & Enterprise
      • Sugar Serve
      • sales-i
    • User Groups
      Professional, Industry, Language
    • Get Involved
      Learn how to become a Raving Fan
    • Social Club
      Live, interactive, virtual meetups with other Sugar customers and Sugar’s Subject Matter experts!
    • Leadership Lounge
      Network with fellow organizational leaders, ask questions, and share insights
    • Developers
      Visit DevClub, the SugarClub group for Sugar Developers
      Developers
      • DevClub
      • Mobile Developers
      • Developer Builds
        Supplemental access level required. Inquiries: developers@sugarcrm.com
    • Additional Groups (Access Required)
      Groups that require special access will be displayed here. Contact sugarclub@sugarcrm.com for assistance. Click here to see all groups
      Additional Groups (Access Required)
      • SugarCloud Platform
  • Product Information
    Product Information
    • Release Central
      Find release-specific content to prepare for your next Sugar update
    • Documentation & Resources
      Looking to expand your Sugar knowledge? Explore our in-depth documentation and other helpful resources!
    • Product Update Blogs
      Updates about each Sugar product
    • Customer Stories »
      Case Studies by SugarCRM
  • Training & Certification
    Training & Certification
    • Training & Certification Home
      Live & On-Demand classes, Quick Videos, Sugar Certifications, and more!
    • Quick Videos
      Short videos about using Sugar
    • My SugarU Dashboard »
    • SugarU News & Updates
  • Adoption
    Adoption
    • Grow Adoption Framework
      Get started on your adoption journey and review the adoption resources from SugarCRM
  • Calendar
  • News
    News
    • Sugar News
    • SugarCRM.com News »
    • Dev Blog
    • SugarCRM Marketplace Blog
  • Help
    Help
    • Welcome to Sugar!
      New to Sugar? Get started here!
    • SugarClub Help & Instructions
      Learn more about SugarClub and find answers to questions about this site
    • New to SugarClub?
      Start your community journey here
    • Technical Support
      Sugar's support resources
      Technical Support
      • Case Portal »
        Access the SugarCRM Case Portal
      • Working with Sugar Support »
        Find out more about engaging with the SugarCRM Support team
      • SugarCloud Information
        Find information about SugarCloud service updates and site status. Contact sugarclub@sugarcrm.com to request access
  • More from Sugar
    More from Sugar
    • DevClub
    • PartnerClub
    • Support
    • SugarOutfitters Marketplace
    • sugarcrm.com
  • DevClub
  • PartnerClub
  • Support
  • Marketplace
  • sugarcrm.com
DevClub
DevClub
Dev Tutorials Sugar 14.1 (Q3 2024) Customization Guide
Click here to join this group and curate your SugarClub experience.
  • +On-Boarding Framework
  • -Customization Guides
    • Sugar 25.1 Customization Guide
    • Sugar 14.2 (Q4 2024) Customization Guide
    • Sugar 14.1 (Q3 2024) Customization Guide
    • Sugar 14.0 (Q2 2024) Customization Guide
    • Sugar 13.3 (Q1 2024) Customization Guide
    • Sugar 13.2 (Q4 2023) Customization Guide
    • Sugar 13.1 (Q3 2023) Customization Guide
    • Sugar 13.0 (Q2 2023) Customization Guide
  • +Modern UI Technical Guide
  • +Automated PHP Compatibility Tool
  • Did you know? Copying related records is a breeze!
  • How to write code for SugarCloud webinar Q&A
  • HOW TO: enforce ACL on Tags
  • Programatically manage Dropdown List
  • Remove custom fields created via package installation
  • Sugar Developer Tools
  • Tutorial:  How to register custom platforms in Sugar instances via Platform extension
  • Adding a google reCAPTCHA in a Web-to-Lead form
  • Sugar Developer Blog Style Guide

Sugar 14.1 (Q3 2024) Customization Guide

The purpose of this document is to provide insight to Sugar Developers for upgrading custom Sugar code, extensions, and integrations to the Sugar 14.1 (Q3 2024) release. This guide focuses on changes in Sugar 14.1 (Q3 2024) that could cause an immediate impact on Sugar customizations and integrations built for earlier Sugar versions.

Please check out the Q3 2024 Developer Webinar recording for more developer highlights. For Admin and End User release notes, please visit the Sugar 14.1.0 Release Notes.

User Experience Updates

AI Summary Dashlet for Opportunities and Cases

We are very excited to introduce AI-driven summarization capabilities to Sugar on Opportunities and Cases modules.

This will empower users to extract key insights and information from their CRM data more efficiently by adding new dashlets to display those summaries in those modules. This feature leverages GPT (Generative Pre-trained Transformer) technology to generate concise and contextually relevant summaries, sentiment etc. of record details. 

Any users with access to Opportunities or Cases can view the dashlet once it is added (see note).

The initial summary will be generated when an opportunity or case record is opened.  The summary will be regenerated once the record view page is refreshed, and new or updated data analyzed by the summary is available. The summary is generated using OpenAI’s most advanced LLM. All data used by the summary is anonymized by SugarCRM before sharing it with OpenAI. 

NOTE: Extra license/cost is required to enable AI Dashlet data.

Static Conversion Rates on Quotes

In this release, we're introducing a concept of Locking Currency Rate in Quote and Quote Line Items (QLIs). Prior to this version, the conversion rate remains dynamic unless the quote is in a closed stage (Closed Dead, Closed Lost, Closed Accepted), furthermore closing the Quote only maintained the currency rate for the original line items. If new items were added later, and the conversion rate had changed in admin>currencies, the new items would adopt the latest conversion rate, thus failing to ensure a truly static rate. 

This solution involved adding a new checkbox field, "Lock Currency Rates." This field, along with the existing Currency Rate field, will be displayed as a field set in the Record View and Record View Dashlet layout (available to be added in different layouts), where users typically work with Quotes and Quoted Line Items. When users select the "Lock Currency Rates" field, the Quote will store the current conversion rates for existing QLIs, and any future QLIs created will maintain the same conversion rate, even if it changes in admin>currencies. If users choose to unlock the "Lock Currency Rate" field, all related RLIs will update to reflect the most recent conversion rate in admin>currencies. 

The addition of this new field allows admins and users to lock currency conversion rates without having to close the Quote, thereby preserving the accurate Quote Stage.

Users will be notified through CONFIRM dialogs when enabling/disabling Lock conversion rate checkbox.

Making Chart Colors consistent in Sugar

In this release, we have implemented a consistent way to assign colors in Sugar. The idea is to use consistent algorithm to pick colors to be rendered across the application.

Every dropdown field, except those dynamically generated – gets a color from the pallet for each value. That color will be used in any chart that shows the data from this dropdown.  

Product Catalog for Serve

In this release, we are enabling Product Catalog for Serve license users, they can easily access and manage product catalog making everything more organized and accessible.

Accessibility Improvements

In this release, we've enhanced Sugar to provide greater accessibility to the user interface, including improvements to VoiceOver and keyboard accessibility commands.

Sugar is now injecting some javascript attributes to the HTML necessary for VoiceOver and Keyboard to properly work with newer browser versions.

Some HTML elements were modified to include such attributes directly in their handlebar templates where injecting wasn't feasible.

Sugar areas that are part of these improvements are:

  • Service Consoles
  • Dropdowns
  • Subpanels and its options (+ and More)
  • Table Headers (sorted tables)
  • Alerts (warning, success, errors)
  • List Views (sorting arrow icon)
  • Column Descriptions

Sugar REST API updates

This Sugar release introduces REST v11_25.

Retrieve record with given sync_key from the query params

Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.

GET <sugar instance>/rest/v11_25/<module>/sync_key?sync_key_field_value=<sync key value>

GET <sugar instance>/rest/v11_25/integrate/<module>/?sync_key_field_name=<sync key field name>&sync_key_field_value=<sync key value>

PATCH/PUT/UPSERT record with given sync_key from the query params

Allows the user to patch a record by sync_key using query params instead of endpoint URL.

PATCH <sugar instance>/rest/v11_25/<module>/sync_key?sync_key_field_value=<sync key value>

PATCH <sugar instance>/rest/v11_25/integrate/<module>/?sync_key_field_name=<sync key field name>&sync_key_field_value=<sync key value>

Delete record with given sync_key from the query params

Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.

DELETE <sugar instance>/rest/v11_25/<module>/sync_key?sync_key_field_value=<sync key value>

DELETE <sugar instance>/rest/v11_25/integrate/<module>/?sync_key_field_name=<sync key field name>&sync_key_field_value=<sync key value>

Configurability updates

Studio

"processed" not allowed as custom field in Moduie Builder

In this release, we are adding processed word to the list of reserved words in Sugar.

You will not be able to use processed as a field name in Module Builder when creating a new module.

For reference, this is the list of disallowed fields in Module Builder:

  • ID
  • ID_C
  • PARENT_NAME
  • PARENT_ID
  • * PROCESSED

Sugar Config Settings

Setting Name

Default

Override Example

Description

moduleInstaller.features.enableRectorModuleScanner false

$sugar_config['moduleInstaller']['packageScan'] = true;

$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner'] = true;

Enables scanning of code of MLPs during installation for compatibility with modern versions of PHP. This occurs in chunks during installation process, so it should also be enabled (moduleInstaller.packageScan). If the package contains incompatible code, installation will be rejected and report provided containing the list of suggested fixes.
pruneDelay 86400000 $sugar_config['pruneDelay'] = 106400000 Adds a delay to the Prune job to take into account the date_modified < today()-pruneDelay used to select the records to be deleted.
moduleInstaller.features.enforceSecureSmarty false $sugar_config['moduleInstaller']['features'][‘enforceSecureSmarty’] = true; When enabled it enforces usage of SecureSmarty instead of Smarty and Sugar_Smarty. SecureSmarty enforces usage of secure Smarty settings.

Removed Functions / Libraries / Features

Upgrade Scripts

Over time our upgrade scripts have accumulated a lot of steps that are likely no longer necessary to to it's version restrictions. In this release, we've removed the deprecated/outdated upgrade scripts.

Platform Updates

Add rector scanner step into PackageScanner during MLP installation

As part of our ongoing efforts to help our customers to install MLPs compatible with PHP 8.2+, we are introducing Rector (compatibility tool) checks to our installation process.

PackageScanner will execute a dry-run of rector looking for incompatibilities on the package being installed and will deny the install if incompatible, if denied, an option to download the Rector report will be available to download the diff file for further investigation.

This feature relies on $sugar_config['moduleInstaller']['features']['enableRectorModuleScanner'] which is disabled by default until further notice.

ExternalResourceClient Enhancements

In this release, we've added the missing pieces you need to make HTTP requests from Sugar without relying on third-party frameworks like curl, guzzle, or any other transport client.

The features we added were:

  • Base Uri:
    • The base URI of the client that is merged into relative URIs

Fullscreen
1
2
3
4
5
6
7
<?php
// Base URI
$baseUri = 'https://httpbin.org/anything/';
$path = 'foo/bar';
$erc = (new ExternalResourceClient())->setBaseUri($baseUri);
$response = $erc->get($path); // Sends request to https://httpbin.org/anything/foo/bar
?>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<?php
// Base URI
$baseUri = 'https://httpbin.org/anything/';
$path = 'foo/bar';
$erc = (new ExternalResourceClient())->setBaseUri($baseUri);
$response = $erc->get($path); // Sends request to https://httpbin.org/anything/foo/bar
?>

  • File downloads
    • The external file may be downloaded into the directory returned by UploadStream::getDir() call (`upload` by default)

Fullscreen
1
2
3
4
5
<?php
$url = 'https://httpbin.org/image/png'; // Url of file to download
$filename = 'img.png'; // Local filename
$response = $erc->download($url, $filename); // Downloads file from $url into `upload` as $filename
?>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<?php
$url = 'https://httpbin.org/image/png'; // Url of file to download
$filename = 'img.png'; // Local filename
$response = $erc->download($url, $filename); // Downloads file from $url into `upload` as $filename
?>

  • Trusted external resources.
    • The new method `ExternalResourceClient::trustTo(...$hosts)` has been added to prevent issues with firewalls.
    • The specified hostnames will not be translated to the corresponding IP addresses.
    • Note: the IP of the target hostname should not belong to the private network (or it should be allowed via $sugar_config['security']['private_ips']).

Fullscreen
1
2
<?php
$erc->trustTo('mytrusted.website.com');
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<?php
$erc->trustTo('mytrusted.website.com');

Note: This functionality has been backported to 13.0.4 and 14.0.1 releases.

Integrate (UPSERT) API Enhancements

In this release, we have improved our Integrate API endpoints to support sync_keys with special characters such as forward slash ("/") that prior to this would be considered part of the endpoint and subsequently fail. In the following example, we are passing the sync_key field name and its value as part of the query string instead of endpoint allowing us to search a sync_key value including "/":

GET:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
// using integrate api
curl --location --request
GET 'https://<instance>/rest/v11_25/integrate/Contacts/?' \
'sync_key_field_name=sync_key&sync_key_field_value=123db%2F002' \
-H 'Content-Type: application/json'
// using module 'sync_key'
curl --location --request
GET 'https://<instance>/rest/v11_25/Contacts/sync_key?'\
'sync_key_field_value=329bc7ec-f745-11ee-8f5b-021b212599db%2F002' \
-H 'Content-Type: application/json'
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// using integrate api
curl --location --request 
  GET 'https://<instance>/rest/v11_25/integrate/Contacts/?' \
      'sync_key_field_name=sync_key&sync_key_field_value=123db%2F002' \
  -H 'Content-Type: application/json' 
  
// using module 'sync_key'
curl --location --request 
  GET 'https://<instance>/rest/v11_25/Contacts/sync_key?'\
  'sync_key_field_value=329bc7ec-f745-11ee-8f5b-021b212599db%2F002' \
  -H 'Content-Type: application/json' 

PATCH/PUT (a.k.a UPSERT):

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
// using integrate API (PATH or PUT) works
curl --location --request
PATCH 'https://<instance>/rest/v11_25/integrate/Accounts/?'\
'sync_key_field_name=sync_key&sync_key_field_value=123db%2F002' \
--data-raw '{"name": "rafa test 1"}' \
-H 'Content-Type: application/json'
// using module 'sync_key'
curl --location --request
PATCH 'https://<instance>/rest/v11_25/Accounts/sync_key' \
'?sync_key_field_value=123db%2F002' \
--data-raw '{"name": "rafa test 1"}' \
-H 'Content-Type: application/json'
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// using integrate API (PATH or PUT) works
curl --location --request 
  PATCH 'https://<instance>/rest/v11_25/integrate/Accounts/?'\
  'sync_key_field_name=sync_key&sync_key_field_value=123db%2F002' \
  --data-raw '{"name": "rafa test 1"}' \
  -H 'Content-Type: application/json' 

// using module 'sync_key'
curl --location --request 
  PATCH 'https://<instance>/rest/v11_25/Accounts/sync_key' \
  '?sync_key_field_value=123db%2F002' \
  --data-raw '{"name": "rafa test 1"}' \
  -H 'Content-Type: application/json' 

DELETE:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
// using integrate API
curl --location --request
DELETE 'https://<instance>/rest/v11_25/integrate/Accounts/?' \
'sync_key_field_name=sync_key&sync_key_field_value=123db%2F002' \
-H 'Content-Type: application/json'
// using module 'sync_key'
curl --location --request
DELETE 'https://<instance>/rest/v11_25/Accounts/sync_key?' \
'sync_key_field_value=123db%2F002' \
-H 'Content-Type: application/json'
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// using integrate API 
curl --location --request 
  DELETE 'https://<instance>/rest/v11_25/integrate/Accounts/?' \
  'sync_key_field_name=sync_key&sync_key_field_value=123db%2F002' \
  -H 'Content-Type: application/json' 

// using module 'sync_key'
curl --location --request 
  DELETE 'https://<instance>/rest/v11_25/Accounts/sync_key?' \
  'sync_key_field_value=123db%2F002' \
  -H 'Content-Type: application/json' 

NOTE: Those improvements were "added" to the current implementation therefore what's currently available is still valid.

Bulk API Enhancements

In this release, we have also improved how we return data from our bulk endpoint where now you can specify which fields you would like to return as part of the bulk endpoint when it is successful.

In the following example, notice that we'd like to get back few extra fields from the record itself, we can by specifying an extra "fields" attribute in the payload. if ['fields'] param provided (it is optional) in the request body (in 'data' param) we handle this as a list of responsive fields. It could be passed via string with fields separated by comma or an array of strings. 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{"requests":[
{
"url":"v11_25/integrate/Contacts/sync_key/sync_key_test",
"method":"PATCH",
"data":{"title":"Recruiting Manager_","name":"2", "fields":["id","sync_key","name","title", "first_name"]}
},
{
"url":"v11_25/integrate/Accounts/sync_key/sync_key_test",
"method":"PATCH",
"data":{"name":"NEw Name", "fields":"1"}
}
]
}
//===== RESPONSE
[
{
"contents": {
"record": {
"id": "dd21a094-e78a-11ee-ac3a-02d786a79729",
"name": "",
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{"requests":[
    {
        "url":"v11_25/integrate/Contacts/sync_key/sync_key_test",
        "method":"PATCH",
        "data":{"title":"Recruiting Manager_","name":"2", "fields":["id","sync_key","name","title", "first_name"]}
    },
        {
        "url":"v11_25/integrate/Accounts/sync_key/sync_key_test",
        "method":"PATCH",
        "data":{"name":"NEw Name", "fields":"1"}
    }
]
}

//===== RESPONSE
[
    {
        "contents": {
            "record": {
                "id": "dd21a094-e78a-11ee-ac3a-02d786a79729",
                "name": "",
                "first_name": "",
                "title": "Recruiting Manager_",
                "sync_key": "sync_key_test"
            }
        },
        "headers": [],
        "status": 200,
        "status_text": "OK"
    },
    {
        "contents": {
            "record": []
        },
        "headers": [],
        "status": 200,
        "status_text": "OK"
    }
]


Enhance the "Prune Database on 1st of Month" Scheduler with time delay criteria

Currently the “Prune Database on 1st of Month“ deletes everything from the database that has the column “deleted“ equal to 1, in this release, we are adding a time sensitive criteria in the query for pruning the database using date_modified, something like: SELECT id FROM table WHERE deleted = 1 AND date_modified < today() - pruneDelay_24h

NOTE: If someone deletes the record through raw queries in the last 24 hours, it will still get picked up by the scheduler, because the date_modified will not be updated.

Restricting Access to Admins Only

In this release, we have added a restriction at the API layer for Admin/Developer Only to access the following modules:

  • Shippers
  • TaxRates
  • Releases
  • Styleguide
  • Roles
  • Teams

Improve TeamSecurity subqueries in ProspectList module

In this release, we have improved the subquery mechanism used on /modules/ProspectLists/ProspectList.php to use \SugarBean::addVisibilityWhere to use an optimized version of queries and make it possible to disable TeamSecurity or apply custom visibility if needed.

Sugar Mobile Metadata Improvements

In this release, we are improving our Sugar Mobile metadata integration to include some extra views to be used by the app to render its customized server side version, those views are:

  • activity-card-content
  • activity-card-definition
  • activity-card-detail
  • activity-card-header
  • activity-timeline

Fix: Portal users can submit cases if disabled with an active token

We have fixed a bug where the user with an active login token gets disabled by an admin could still use the portal until its token expired. Now, at the time of disabling, Sugar will invalidate all tokens for that particular user, cutting access to anything active.

Note: This functionality has been backported to 13.0.4 and 14.0.1 releases.

Introducing SecureSmarty

In this release, we are introducing SecureSmarty a safer replacement to Smarty, SugarPdfSmarty, Sugar_Smarty. This new class enforces usage of secure Smarty settings preventing the use of unsecure functions that could potentially endanger your instance.

After upgrade, when this feature is enabled (see $sugar_config['moduleInstaller']['features'][‘enforceSecureSmarty’]), PackageScanner will not allow those classes (Smarty, SugarPdfSmarty, Sugar_Smarty) to be used in MLP/Addons and they'll have to be replaced with SecureSmarty.

Note: This feature is disabled in 14.1 and will automatically enabled in 14.2.

Sanitizing data in templates

In this release, variables in templates will be escaped according to the context they are used.

  • Smarty has modifiers to escape variables, most of the variables are already escaped
  • Hanldebars escapes variables by default if you use {{. Places that use {{{ should be sanitized with {sanitize}
  • XTemplate doesn’t have any functionality to escape variables and uses them as is. We are escaping data before passing to the template and/or introduce modifiers when necessary/

Sugar Core Security Updates

As part of our ongoing efforts to keep Sugar clean, fast, reliable, and most importantly secure, we have updated Sugar Core code in different areas of the application such as Package Scanner, Module Installer, UI rendering, Handlebar templates, File Uploads and Imports.

Sugar Core readiness to PHP 8.3

We are constantly conducting code reviews making Sugar compatible with the latest versions PHP, in this case PHP 8.3. Sugar Core is now fully compatible with PHP 8.2 and PHP 8.3. We leverage the use of Rector for this work.

Denylist Updates

In this release, we are adding the following functions to the PackageScanner's denylist:
  • show_source()
  • php_strip_whitespace()
  • highlight_file() 

When $sugar_config['moduleInstaller']['features'][‘enforceSecureSmarty’]), gets enabled, these classes will be added to the PackageScanner's denylist:

  • Smarty
  • SugarPdfSmarty
  • Sugar_Smarty
  • Sugar Q3 2024
  • Sugar 14.1
  • 0 comments
  • 0 members are here
  • Sign in to reply
Related
Recommended