<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://sugarclub.sugarai.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Sugar 14.1 (Q3 2024) Customization Guide</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Sugar 14.1 (Q3 2024) Customization Guide</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide</link><pubDate>Tue, 16 Jul 2024 17:57:55 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:06fade0c-5fd1-46be-80e5-9004b949ce64</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide#comments</comments><description>Current Revision posted to Dev Tutorials by Rafael Fernandes on 7/16/2024 5:57:55 PM&lt;br /&gt;
&lt;div class="content"&gt;
&lt;div class="content"&gt;
&lt;p&gt;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&amp;nbsp;&lt;span&gt;14.1 (Q&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2024) that could cause an immediate impact on Sugar customizations and integrations built for earlier Sugar versions.&lt;/p&gt;
&lt;p&gt;Please check out the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="/dev-club/m/event-recaps/2801"&gt;Q3 2024 Developer Webinar recording&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for more developer highlights.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;For Admin and End User release notes, please visit the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Release_Notes/14.1.0_Release_Notes/"&gt;Sugar 14.1.0 Release Notes&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1ff80k9i32"&gt;User Experience Updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;AI Summary Dashlet for Opportunities and Cases&lt;/h3&gt;
&lt;p&gt;We are very excited to introduce&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;AI-driven&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;summarization capabilities to Sugar on Opportunities and Cases modules.&lt;/p&gt;
&lt;p&gt;This will empower users to extract key insights and information from their CRM data more efficiently by adding&lt;span class="TextRun SCXW260305411 BCX0" lang="EN-US" data-contrast="auto"&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&amp;nbsp;new&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SpellingErrorV2Themed SCXW260305411 BCX0"&gt;dashlets&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&amp;nbsp;to display those summaries&amp;nbsp;in those modules.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;Th&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;is&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;feature leverages GPT (Generative Pre-trained Transformer) technology to generate concise and contextually relevant summaries, sentiment etc. of record details.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW260305411 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;Any users with access to Opportunities or Cases can view the dashlet once it is added (see note).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;The initial summary will be generated when an opportunity or case record is opened.&amp;nbsp; 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&amp;rsquo;s most advanced LLM. All data used by the summary is anonymized by SugarCRM before sharing it with OpenAI.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&amp;nbsp;Extra license/cost is required to enable AI Dashlet data.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Static Conversion Rates on Quotes&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;,&amp;nbsp;we&amp;#39;re introducing a concept of Locking&amp;nbsp;Currency Rate in Quote and Quote Line Items (QLIs). Prior to this version,&amp;nbsp;the conversion rate remains dynamic unless the quote is in a closed stage (&lt;span class="TextRun SCXW88795868 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW88795868 BCX0"&gt;Closed Dead, Closed Lost, Closed Accepted&lt;/span&gt;&lt;/span&gt;), furthermore&amp;nbsp;&lt;span class="TextRun SCXW236130893 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;closing the Quote only&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;maintained&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the currency rate for the original line items. If&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;new items&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;were added later, and the conversion rate had changed in admin&amp;gt;currencies, the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;new items&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;would adopt the latest conversion rate, thus&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;failing to ensure&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;a truly static rate.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="TextRun SCXW7993086 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;This solution involved adding a new checkbox field, &amp;quot;Lock Currency Rates.&amp;quot; This field, along with the existing Currency Rate field,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;will be displayed as a field set&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;in the Record View and Record View&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Dashlet&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;layout&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(available to be added in different layouts)&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;, where users typically work with Quotes and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Quoted&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Line&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Items. When users select the &amp;quot;Lock Currency Rates&amp;quot; field, the Quote will store the current conversion rates for existing QLIs, and any future QLIs created will&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;maintain&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the same conversion rate, even if it changes in admin&amp;gt;currencies. If users choose to unlock the &amp;quot;Lock Currency Rate&amp;quot; field, all related RLIs will update to reflect the most recent&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;conversion&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;rate in admin&amp;gt;currencies.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;The addition of this new field allows admins and users to lock currency conversion rates without having to close the Quote, thereby preserving the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;accurate&lt;/span&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Quote Stage.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;Users will be notified through CONFIRM dialogs when enabling/disabling Lock conversion rate checkbox.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Making Chart Colors consistent in Sugar&lt;/h3&gt;
&lt;p&gt;In this release, we have implemented a consistent way to assign colors in Sugar. The idea is to&amp;nbsp;use consistent algorithm to pick colors to be rendered across the application.&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;Every dropdown field, except those dynamically generated &amp;ndash; gets a color from the pallet for each value. That color will be used in any chart that shows the data from this dropdown.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Product Catalog for Serve&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;,&amp;nbsp;we are enabling Product Catalog for Serve license users, they&lt;span class="TextRun SCXW50559475 BCX0" lang="EN-US" data-contrast="auto"&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;&amp;nbsp;can easily access and manage product&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;catalog&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;making everything more organized and accessible.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Accessibility&amp;nbsp;Improvements&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;, we&amp;#39;ve enhanced Sugar to provide greater accessibility to the user interface, including improvements to VoiceOver and keyboard accessibility commands.&lt;/p&gt;
&lt;p&gt;Sugar is now injecting some javascript&amp;nbsp;attributes to the HTML necessary for VoiceOver and Keyboard to properly work with newer browser versions.&lt;/p&gt;
&lt;p&gt;Some HTML elements were modified to include such attributes directly in their handlebar templates where injecting wasn&amp;#39;t feasible.&lt;/p&gt;
&lt;p&gt;Sugar areas that are part of these improvements are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Service Consoles&lt;/li&gt;
&lt;li&gt;Dropdowns&lt;/li&gt;
&lt;li&gt;Subpanels and its options (+ and More)&lt;/li&gt;
&lt;li&gt;Table Headers (sorted tables)&lt;/li&gt;
&lt;li&gt;Alerts (warning, success, errors)&lt;/li&gt;
&lt;li&gt;List Views (sorting arrow icon)&lt;/li&gt;
&lt;li&gt;Column Descriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl10"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1givqvoho2"&gt;&lt;span&gt;&lt;span class="NormalTextRun SCXW249156672 BCX0"&gt;&lt;/span&gt;&lt;/span&gt;Sugar REST API updates&lt;/h3&gt;
&lt;p&gt;This Sugar release introduces REST&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;v11_25&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;Retrieve record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;GET &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;GET &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;PATCH/PUT/UPSERT&amp;nbsp;record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to&amp;nbsp;patch a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;PATCH &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;PATCH &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;Delete&amp;nbsp;record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;DELETE &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;DELETE &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1hv2v4rq60"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h2 id="mcetoc_1ff80k9i33"&gt;Configurability&amp;nbsp;updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1f7c87abe2"&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1f7c8nhce4"&gt;&lt;strong&gt;Studio&lt;/strong&gt;&lt;/h3&gt;
&lt;h4&gt;&amp;quot;processed&amp;quot; not allowed as custom field in Moduie Builder&lt;/h4&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;p&gt;In this release, we are adding&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;processed&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;word&amp;nbsp;to the list of reserved words in Sugar.&lt;/p&gt;
&lt;p&gt;You will not be able to use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;processed&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;as a field name in Module Builder when creating a new module.&lt;/p&gt;
&lt;p&gt;For reference,&amp;nbsp;this is the list of disallowed fields in Module Builder:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;ID_C&lt;/li&gt;
&lt;li&gt;PARENT_NAME&lt;/li&gt;
&lt;li&gt;PARENT_ID&lt;/li&gt;
&lt;li&gt;* PROCESSED&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1f77psegv7"&gt;Sugar Config Settings&lt;/h3&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Setting Name&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Override Example&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;moduleInstaller.features.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;enableRectorModuleScanner&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span&gt;$sugar_config['moduleInstaller']['packageScan'] = true;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner'] = true;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Enables scanning of code of MLPs&amp;nbsp;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.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;pruneDelay&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;86400000&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$sugar_config[&amp;#39;&lt;/span&gt;&lt;span&gt;pruneDelay&amp;#39;] =&amp;nbsp;10&lt;/span&gt;&lt;span&gt;6400000&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Adds a delay to the Prune job to take into account the date_modified &amp;lt; today()-pruneDelay used to select the records to be deleted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;moduleInstaller.features.enforceSecureSmarty&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;] = true;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;When enabled it enforces usage of SecureSmarty instead of Smarty and Sugar_Smarty. SecureSmarty enforces usage of secure Smarty settings.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="mcetoc_1f77psegvb"&gt;Removed Functions / Libraries / Features&lt;/h2&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Upgrade Scripts&lt;/h3&gt;
&lt;p&gt;Over time our upgrade scripts have accumulated a lot of steps that are likely no longer necessary to to it&amp;#39;s version restrictions. In this release, we&amp;#39;ve removed the deprecated/outdated upgrade scripts.&lt;/p&gt;
&lt;h2 id="mcetoc_1f77psegvl"&gt;Platform Updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1gqa6vaoc8"&gt;&lt;span&gt;Add rector scanner step into PackageScanner during MLP installation&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This feature&amp;nbsp;relies on&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner']&lt;/code&gt;&amp;nbsp;which is&amp;nbsp;&lt;strong&gt;disabled&lt;/strong&gt;&amp;nbsp;by default until further notice.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;ExternalResourceClient&amp;nbsp;Enhancements&lt;/h3&gt;
&lt;p&gt;In this release,&amp;nbsp;we&amp;#39;ve added&amp;nbsp;t&lt;span&gt;he missing pieces&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;you need to make HTTP requests from Sugar without relying on third-party frameworks like curl, guzzle, or any other transport client.&lt;/p&gt;
&lt;p&gt;The features we added were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Base Uri:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The base URI of the client that is merged into relative URIs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;
&amp;lt;?php
// Base URI
$baseUri = &amp;#39;https://httpbin.org/anything/&amp;#39;;
$path = &amp;#39;foo/bar&amp;#39;;
$erc = (new ExternalResourceClient())-&amp;gt;setBaseUri($baseUri);
$response = $erc-&amp;gt;get($path); // Sends request to https://httpbin.org/anything/foo/bar
?&amp;gt;

&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File downloads&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The external file may be downloaded into the directory returned by&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;UploadStream::getDir()&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;call (`upload` by default)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$url = &amp;#39;https://httpbin.org/image/png&amp;#39;; // Url of file to download
$filename = &amp;#39;img.png&amp;#39;; // Local filename
$response = $erc-&amp;gt;download($url, $filename); // Downloads file from $url into `upload` as $filename
?&amp;gt;

&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Trusted external resources.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The new method `&lt;code&gt;ExternalResourceClient::trustTo(...$hosts)&lt;/code&gt;` has been added to prevent issues with firewalls.&lt;/li&gt;
&lt;li&gt;The specified hostnames will not be translated to the corresponding IP addresses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the IP of the target hostname should not belong to the private network (or it should be allowed via&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;$sugar_config['security']['private_ips']).&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$erc-&amp;gt;trustTo(&amp;#39;mytrusted.website.com&amp;#39;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;This functionality has been backported to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;13.0.4&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;14.0.1&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;releases.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Integrate (UPSERT) API Enhancements&lt;/h3&gt;
&lt;p&gt;In this release, we have improved our Integrate API endpoints to support&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;sync_keys&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;with&amp;nbsp;special characters such as forward slash (&amp;quot;/&amp;quot;) 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 &amp;quot;/&amp;quot;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GET:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate api
curl --location --request 
  GET &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Contacts/?&amp;#39; \
      &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 
  
// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  GET &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Contacts/sync_key?&amp;#39;\
  &amp;#39;sync_key_field_value=329bc7ec-f745-11ee-8f5b-021b212599db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PATCH/PUT (a.k.a UPSERT):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate API (PATH or PUT) works
curl --location --request 
  PATCH &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Accounts/?&amp;#39;\
  &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  --data-raw &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;rafa test 1&amp;quot;}&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 

// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  PATCH &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Accounts/sync_key&amp;#39; \
  &amp;#39;?sync_key_field_value=123db%2F002&amp;#39; \
  --data-raw &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;rafa test 1&amp;quot;}&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DELETE:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate API 
curl --location --request 
  DELETE &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Accounts/?&amp;#39; \
  &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 

// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  DELETE &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Accounts/sync_key?&amp;#39; \
  &amp;#39;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Those improvements were &amp;quot;added&amp;quot; to the current implementation therefore what&amp;#39;s currently available is still valid.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Bulk API Enhancements&lt;/h3&gt;
&lt;p&gt;In this release, we have also improved how we return data from our&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;bulk&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;endpoint where now you can specify which fields you would like to return as part of the bulk endpoint when it is successful.&lt;/p&gt;
&lt;p&gt;In the following example, notice that we&amp;#39;d like to get back few&amp;nbsp;extra fields from the record itself, we can by specifying an extra &amp;quot;fields&amp;quot; attribute in the payload. if [&amp;#39;&lt;code&gt;fields&lt;/code&gt;&amp;#39;] param provided (it is optional) in the request body (in &amp;#39;&lt;code&gt;data&lt;/code&gt;&amp;#39; 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.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="javascript"&gt;{&amp;quot;requests&amp;quot;:[
    {
        &amp;quot;url&amp;quot;:&amp;quot;v11_25/integrate/Contacts/sync_key/sync_key_test&amp;quot;,
        &amp;quot;method&amp;quot;:&amp;quot;PATCH&amp;quot;,
        &amp;quot;data&amp;quot;:{&amp;quot;title&amp;quot;:&amp;quot;Recruiting Manager_&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;2&amp;quot;, &amp;quot;fields&amp;quot;:[&amp;quot;id&amp;quot;,&amp;quot;sync_key&amp;quot;,&amp;quot;name&amp;quot;,&amp;quot;title&amp;quot;, &amp;quot;first_name&amp;quot;]}
    },
        {
        &amp;quot;url&amp;quot;:&amp;quot;v11_25/integrate/Accounts/sync_key/sync_key_test&amp;quot;,
        &amp;quot;method&amp;quot;:&amp;quot;PATCH&amp;quot;,
        &amp;quot;data&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;NEw Name&amp;quot;, &amp;quot;fields&amp;quot;:&amp;quot;1&amp;quot;}
    }
]
}

//===== RESPONSE
[
    {
        &amp;quot;contents&amp;quot;: {
            &amp;quot;record&amp;quot;: {
                &amp;quot;id&amp;quot;: &amp;quot;dd21a094-e78a-11ee-ac3a-02d786a79729&amp;quot;,
                &amp;quot;name&amp;quot;: &amp;quot;&amp;quot;,
                &amp;quot;first_name&amp;quot;: &amp;quot;&amp;quot;,
                &amp;quot;title&amp;quot;: &amp;quot;Recruiting Manager_&amp;quot;,
                &amp;quot;sync_key&amp;quot;: &amp;quot;sync_key_test&amp;quot;
            }
        },
        &amp;quot;headers&amp;quot;: [],
        &amp;quot;status&amp;quot;: 200,
        &amp;quot;status_text&amp;quot;: &amp;quot;OK&amp;quot;
    },
    {
        &amp;quot;contents&amp;quot;: {
            &amp;quot;record&amp;quot;: []
        },
        &amp;quot;headers&amp;quot;: [],
        &amp;quot;status&amp;quot;: 200,
        &amp;quot;status_text&amp;quot;: &amp;quot;OK&amp;quot;
    }
]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Enhance the &amp;quot;Prune Database on 1st of Month&amp;quot; Scheduler with time delay criteria&lt;/h3&gt;
&lt;p&gt;Currently the &amp;ldquo;Prune Database on 1st of Month&amp;ldquo; deletes everything from the database that has the column &amp;ldquo;deleted&amp;ldquo; equal to 1, in this release, we are adding a time sensitive&lt;span&gt;&amp;nbsp;criteria in the query for pruning the database&amp;nbsp;using date_modified, something like:&lt;code&gt;&amp;nbsp;SELECT&amp;nbsp;id&amp;nbsp;FROM table&amp;nbsp;WHERE deleted = 1 AND date_modified &amp;lt; today() - pruneDelay_24h&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;:&amp;nbsp;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Restricting Access to Admins Only&lt;/h3&gt;
&lt;p&gt;In this release, we have added a restriction at the API&amp;nbsp;layer for Admin/Developer Only to access the following modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shippers&lt;/li&gt;
&lt;li&gt;TaxRates&lt;/li&gt;
&lt;li&gt;Releases&lt;/li&gt;
&lt;li&gt;Styleguide&lt;/li&gt;
&lt;li&gt;Roles&lt;/li&gt;
&lt;li&gt;Teams&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Improve TeamSecurity subqueries in ProspectList module&lt;/h3&gt;
&lt;p&gt;In this release,&amp;nbsp;we have improved the subquery mechanism used on&amp;nbsp;&lt;span&gt;/modules/ProspectLists/ProspectList.php to use&amp;nbsp;&lt;code&gt;\SugarBean::addVisibilityWhere&lt;/code&gt;&amp;nbsp;to use an optimized version of queries and make it possible to disable TeamSecurity or apply custom visibility if needed.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Mobile Metadata Improvements&lt;/h3&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;activity-card-content&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-definition&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-detail&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-header&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-timeline&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Fix: Portal users can submit cases if disabled with an active token&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;This functionality has been&lt;span&gt;&amp;nbsp;&lt;/span&gt;backported to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;13.0.4&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;14.0.1&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;releases.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Introducing SecureSmarty&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In this release, we are&amp;nbsp;introducing&amp;nbsp;&lt;code&gt;SecureSmarty&lt;/code&gt;&amp;nbsp;a safer replacement to&amp;nbsp;&lt;code&gt;Smarty,&amp;nbsp;SugarPdfSmarty,&lt;/code&gt;&amp;nbsp;&lt;code&gt;Sugar_Smarty&lt;/code&gt;. This new class enforces usage of secure Smarty settings preventing the use of unsecure functions that could potentially endanger your instance.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;After upgrade, when this feature is enabled (see&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;]&lt;/code&gt;), PackageScanner will not allow those classes (&lt;code&gt;Smarty,&amp;nbsp;SugarPdfSmarty,&lt;/code&gt;&amp;nbsp;&lt;code&gt;Sugar_Smarty&lt;/code&gt;) to be used in MLP/Addons and they&amp;#39;ll have to be replaced with&amp;nbsp;&lt;code&gt;SecureSmarty&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Note: This feature is disabled in&amp;nbsp;&lt;code&gt;14.1&lt;/code&gt;&amp;nbsp;and will automatically enabled in&amp;nbsp;&lt;code&gt;14.2&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sanitizing data&amp;nbsp;in templates&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In this release, v&lt;/span&gt;ariables in templates&amp;nbsp;will be escaped according to the context they are used.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Smarty has modifiers to escape variables, most of the variables are already escaped&lt;/li&gt;
&lt;li&gt;Hanldebars escapes variables by default if you use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{{&lt;/code&gt;. Places that use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{{{&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;should be sanitized with&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{sanitize}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;XTemplate doesn&amp;rsquo;t have any functionality to escape variables and uses them as is. We&amp;nbsp;are&amp;nbsp;escaping data before passing to the template and/or introduce modifiers&amp;nbsp;when necessary/&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Core Security Updates&lt;/h3&gt;
&lt;p&gt;As part of our ongoing efforts to keep Sugar clean, fast, reliable, and most importantly secure, we have updated&amp;nbsp;Sugar Core code in different areas of the application such as Package Scanner, Module Installer, UI rendering, Handlebar templates, File Uploads and Imports.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Core&amp;nbsp;readiness to PHP 8.3&lt;/h3&gt;
&lt;p&gt;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&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="/dev-club/w/dev-tutorials/819/automated-php-compatibility-tool"&gt;Rector&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for this work.&lt;/p&gt;
&lt;h2 id="mcetoc_1f77psegv7"&gt;Denylist Updates&lt;/h2&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;span&gt;In this release, we are adding the following&amp;nbsp;functions to the PackageScanner&amp;#39;s denylist:&lt;/span&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;show_source()&lt;/code&gt;&lt;/li&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;php_strip_whitespace()&lt;/code&gt;&lt;/li&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;highlight_file()&amp;nbsp;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;p&gt;&lt;span&gt;When&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;]&lt;/code&gt;), gets enabled, these classes will be added to the PackageScanner&amp;#39;s denylist:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;Smarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;SugarPdfSmarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;Sugar_Smarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Sugar Q3 2024, Sugar 14.1&lt;/div&gt;
</description></item><item><title>Sugar 14.1 (Q3 2024) Customization Guide</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide/revision/3</link><pubDate>Mon, 15 Jul 2024 13:23:57 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:06fade0c-5fd1-46be-80e5-9004b949ce64</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide#comments</comments><description>Revision 3 posted to Dev Tutorials by Rafael Fernandes on 7/15/2024 1:23:57 PM&lt;br /&gt;
&lt;div class="content"&gt;
&lt;div class="content"&gt;
&lt;p&gt;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&amp;nbsp;&lt;span&gt;14.1 (Q&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2024) that could cause an immediate impact on Sugar customizations and integrations built for earlier Sugar versions.&lt;/p&gt;
&lt;p&gt;Please check out the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="/dev-club/m/event-recaps/2801"&gt;Q3 2024 Developer Webinar recording&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for more developer highlights.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;For Admin and End User release notes, please visit the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Release_Notes/14.1.0_Release_Notes/"&gt;Sugar 14.1.0 Release Notes&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1ff80k9i32"&gt;User Experience Updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;AI Summary Dashlet for Opportunities and Cases&lt;/h3&gt;
&lt;p&gt;We are very excited to introduce&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;AI-driven&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;summarization capabilities to Sugar on Opportunities and Cases modules.&lt;/p&gt;
&lt;p&gt;This will empower users to extract key insights and information from their CRM data more efficiently by adding&lt;span class="TextRun SCXW260305411 BCX0" lang="EN-US" data-contrast="auto"&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&amp;nbsp;new&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SpellingErrorV2Themed SCXW260305411 BCX0"&gt;dashlets&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&amp;nbsp;to display those summaries&amp;nbsp;in those modules.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;Th&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;is&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;feature leverages GPT (Generative Pre-trained Transformer) technology to generate concise and contextually relevant summaries, sentiment etc. of record details.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW260305411 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;Any users with access to Opportunities or Cases can view the dashlet once it is added (see note).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;The initial summary will be generated when an opportunity or case record is opened.&amp;nbsp; 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&amp;rsquo;s most advanced LLM. All data used by the summary is anonymized by SugarCRM before sharing it with OpenAI.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&amp;nbsp;Extra license/cost is required to enable AI Dashlet data.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Static Conversion Rates on Quotes&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;,&amp;nbsp;we&amp;#39;re introducing a concept of Locking&amp;nbsp;Currency Rate in Quote and Quote Line Items (QLIs). Prior to this version,&amp;nbsp;the conversion rate remains dynamic unless the quote is in a closed stage (&lt;span class="TextRun SCXW88795868 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW88795868 BCX0"&gt;Closed Dead, Closed Lost, Closed Accepted&lt;/span&gt;&lt;/span&gt;), furthermore&amp;nbsp;&lt;span class="TextRun SCXW236130893 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;closing the Quote only&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;maintained&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the currency rate for the original line items. If&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;new items&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;were added later, and the conversion rate had changed in admin&amp;gt;currencies, the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;new items&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;would adopt the latest conversion rate, thus&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;failing to ensure&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;a truly static rate.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="TextRun SCXW7993086 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;This solution involved adding a new checkbox field, &amp;quot;Lock Currency Rates.&amp;quot; This field, along with the existing Currency Rate field,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;will be displayed as a field set&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;in the Record View and Record View&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Dashlet&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;layout&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(available to be added in different layouts)&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;, where users typically work with Quotes and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Quoted&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Line&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Items. When users select the &amp;quot;Lock Currency Rates&amp;quot; field, the Quote will store the current conversion rates for existing QLIs, and any future QLIs created will&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;maintain&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the same conversion rate, even if it changes in admin&amp;gt;currencies. If users choose to unlock the &amp;quot;Lock Currency Rate&amp;quot; field, all related RLIs will update to reflect the most recent&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;conversion&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;rate in admin&amp;gt;currencies.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;The addition of this new field allows admins and users to lock currency conversion rates without having to close the Quote, thereby preserving the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;accurate&lt;/span&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Quote Stage.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;Users will be notified through CONFIRM dialogs when enabling/disabling Lock conversion rate checkbox.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Making Chart Colors consistent in Sugar&lt;/h3&gt;
&lt;p&gt;In this release, we have implemented a consistent way to assign colors in Sugar. The idea is to&amp;nbsp;use consistent algorithm to pick colors to be rendered across the application.&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;Every dropdown field, except those dynamically generated &amp;ndash; gets a color from the pallet for each value. That color will be used in any chart that shows the data from this dropdown.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Product Catalog for Serve&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;,&amp;nbsp;we are enabling Product Catalog for Serve license users, they&lt;span class="TextRun SCXW50559475 BCX0" lang="EN-US" data-contrast="auto"&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;&amp;nbsp;can easily access and manage product&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;catalog&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;making everything more organized and accessible.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Accessibility&amp;nbsp;Improvements&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;, we&amp;#39;ve enhanced Sugar to provide greater accessibility to the user interface, including improvements to VoiceOver and keyboard accessibility commands.&lt;/p&gt;
&lt;p&gt;Sugar is now injecting some javascript&amp;nbsp;attributes to the HTML necessary for VoiceOver and Keyboard to properly work with newer browser versions.&lt;/p&gt;
&lt;p&gt;Some HTML elements were modified to include such attributes directly in their handlebar templates where injecting wasn&amp;#39;t feasible.&lt;/p&gt;
&lt;p&gt;Sugar areas that are part of these improvements are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Service Consoles&lt;/li&gt;
&lt;li&gt;Dropdowns&lt;/li&gt;
&lt;li&gt;Subpanels and its options (+ and More)&lt;/li&gt;
&lt;li&gt;Table Headers (sorted tables)&lt;/li&gt;
&lt;li&gt;Alerts (warning, success, errors)&lt;/li&gt;
&lt;li&gt;List Views (sorting arrow icon)&lt;/li&gt;
&lt;li&gt;Column Descriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl10"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1givqvoho2"&gt;&lt;span&gt;&lt;span class="NormalTextRun SCXW249156672 BCX0"&gt;&lt;/span&gt;&lt;/span&gt;Sugar REST API updates&lt;/h3&gt;
&lt;p&gt;This Sugar release introduces REST&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;v11_25&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;Retrieve record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;GET &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;GET &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;PATCH/PUT/UPSERT&amp;nbsp;record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to&amp;nbsp;patch a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;PATCH &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;PATCH &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;Delete&amp;nbsp;record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;DELETE &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;DELETE &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1hv2v4rq60"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h2 id="mcetoc_1ff80k9i33"&gt;Configurability&amp;nbsp;updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1f7c87abe2"&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1f7c8nhce4"&gt;&lt;strong&gt;Studio&lt;/strong&gt;&lt;/h3&gt;
&lt;h4&gt;&amp;quot;processed&amp;quot; not allowed as custom field in Moduie Builder&lt;/h4&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;p&gt;In this release, we are adding&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;processed&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;word&amp;nbsp;to the list of reserved words in Sugar.&lt;/p&gt;
&lt;p&gt;You will not be able to use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;processed&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;as a field name in Module Builder when creating a new module.&lt;/p&gt;
&lt;p&gt;For reference,&amp;nbsp;this is the list of disallowed fields in Module Builder:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;ID_C&lt;/li&gt;
&lt;li&gt;PARENT_NAME&lt;/li&gt;
&lt;li&gt;PARENT_ID&lt;/li&gt;
&lt;li&gt;* PROCESSED&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1f77psegv7"&gt;Sugar Config Settings&lt;/h3&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Setting Name&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Override Example&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;moduleInstaller.features.enableRectorModuleScanner&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span&gt;$sugar_config['moduleInstaller']['packageScan'] = true;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner'] = true;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Enables scanning of code of MLPs before installation for compatibility with modern versions of PHP. This occurs as one of the stages in Package Scanner, 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.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;pruneDelay&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;86400000&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$sugar_config[&amp;#39;&lt;/span&gt;&lt;span&gt;pruneDelay&amp;#39;] =&amp;nbsp;10&lt;/span&gt;&lt;span&gt;6400000&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Adds a delay to the Prune job to take into account the date_modified &amp;lt; today()-pruneDelay used to select the records to be deleted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;moduleInstaller.features.enforceSecureSmarty&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;] = true;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;When enabled it enforces usage of SecureSmarty instead of Smarty and Sugar_Smarty. SecureSmarty enforces usage of secure Smarty settings.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="mcetoc_1f77psegvb"&gt;Removed Functions / Libraries / Features&lt;/h2&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Upgrade Scripts&lt;/h3&gt;
&lt;p&gt;Over time our upgrade scripts have accumulated a lot of steps that are likely no longer necessary to to it&amp;#39;s version restrictions. In this release, we&amp;#39;ve removed the deprecated/outdated upgrade scripts.&lt;/p&gt;
&lt;h2 id="mcetoc_1g4djj0su0"&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1f77psegvl"&gt;Platform Updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1gqa6vaoc8"&gt;&lt;span&gt;Add rector scanner step into PackageScanner during MLP installation&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;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 ModuleLoader.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This feature&amp;nbsp;relies on&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner']&lt;/code&gt;&amp;nbsp;which is&amp;nbsp;&lt;strong&gt;disabled&lt;/strong&gt;&amp;nbsp;by default until further notice.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;ExternalResourceClient&amp;nbsp;Enhancements&lt;/h3&gt;
&lt;p&gt;In this release,&amp;nbsp;we&amp;#39;ve added&amp;nbsp;t&lt;span&gt;he missing pieces&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;you need to make HTTP requests from Sugar without relying on third-party frameworks like curl, guzzle, or any other transport client.&lt;/p&gt;
&lt;p&gt;The features we added were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Base Uri:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The base URI of the client that is merged into relative URIs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;
&amp;lt;?php
// Base URI
$baseUri = &amp;#39;https://httpbin.org/anything/&amp;#39;;
$path = &amp;#39;foo/bar&amp;#39;;
$erc = (new ExternalResourceClient())-&amp;gt;setBaseUri($baseUri);
$response = $erc-&amp;gt;get($path); // Sends request to https://httpbin.org/anything/foo/bar
?&amp;gt;

&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File downloads&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The external file may be downloaded into the directory returned by&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;UploadStream::getDir()&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;call (`upload` by default)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$url = &amp;#39;https://httpbin.org/image/png&amp;#39;; // Url of file to download
$filename = &amp;#39;img.png&amp;#39;; // Local filename
$response = $erc-&amp;gt;download($url, $filename); // Downloads file from $url into `upload` as $filename
?&amp;gt;

&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Trusted external resources.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The new method `&lt;code&gt;ExternalResourceClient::trustTo(...$hosts)&lt;/code&gt;` has been added to prevent issues with firewalls.&lt;/li&gt;
&lt;li&gt;The specified hostnames will not be translated to the corresponding IP addresses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the IP of the target hostname should not belong to the private network (or it should be allowed via&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;$sugar_config['security']['private_ips']).&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$erc-&amp;gt;trustTo(&amp;#39;mytrusted.website.com&amp;#39;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;This functionality has been backported to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;13.0.4&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;14.0.1&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;releases.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Integrate (UPSERT) API Enhancements&lt;/h3&gt;
&lt;p&gt;In this release, we have improved our Integrate API endpoints to support&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;sync_keys&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;with&amp;nbsp;special characters such as forward slash (&amp;quot;/&amp;quot;) 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 &amp;quot;/&amp;quot;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GET:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate api
curl --location --request 
  GET &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Contacts/?&amp;#39; \
      &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 
  
// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  GET &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Contacts/sync_key?&amp;#39;\
  &amp;#39;sync_key_field_value=329bc7ec-f745-11ee-8f5b-021b212599db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PATCH/PUT (a.k.a UPSERT):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate API (PATH or PUT) works
curl --location --request 
  PATCH &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Accounts/?&amp;#39;\
  &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  --data-raw &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;rafa test 1&amp;quot;}&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 

// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  PATCH &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Accounts/sync_key&amp;#39; \
  &amp;#39;?sync_key_field_value=123db%2F002&amp;#39; \
  --data-raw &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;rafa test 1&amp;quot;}&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DELETE:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate API 
curl --location --request 
  DELETE &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Accounts/?&amp;#39; \
  &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 

// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  DELETE &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Accounts/sync_key?&amp;#39; \
  &amp;#39;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Those improvements were &amp;quot;added&amp;quot; to the current implementation therefore what&amp;#39;s currently available is still valid.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Bulk API Enhancements&lt;/h3&gt;
&lt;p&gt;In this release, we have also improved how we return data from our&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;bulk&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;endpoint where now you can specify which fields you would like to return as part of the bulk endpoint when it is successful.&lt;/p&gt;
&lt;p&gt;In the following example, notice that we&amp;#39;d like to get back few&amp;nbsp;extra fields from the record itself, we can by specifying an extra &amp;quot;fields&amp;quot; attribute in the payload. if [&amp;#39;&lt;code&gt;fields&lt;/code&gt;&amp;#39;] param provided (it is optional) in the request body (in &amp;#39;&lt;code&gt;data&lt;/code&gt;&amp;#39; 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.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="javascript"&gt;{&amp;quot;requests&amp;quot;:[
    {
        &amp;quot;url&amp;quot;:&amp;quot;v11_25/integrate/Contacts/sync_key/sync_key_test&amp;quot;,
        &amp;quot;method&amp;quot;:&amp;quot;PATCH&amp;quot;,
        &amp;quot;data&amp;quot;:{&amp;quot;title&amp;quot;:&amp;quot;Recruiting Manager_&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;2&amp;quot;, &amp;quot;fields&amp;quot;:[&amp;quot;id&amp;quot;,&amp;quot;sync_key&amp;quot;,&amp;quot;name&amp;quot;,&amp;quot;title&amp;quot;, &amp;quot;first_name&amp;quot;]}
    },
        {
        &amp;quot;url&amp;quot;:&amp;quot;v11_25/integrate/Accounts/sync_key/sync_key_test&amp;quot;,
        &amp;quot;method&amp;quot;:&amp;quot;PATCH&amp;quot;,
        &amp;quot;data&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;NEw Name&amp;quot;, &amp;quot;fields&amp;quot;:&amp;quot;1&amp;quot;}
    }
]
}

//===== RESPONSE
[
    {
        &amp;quot;contents&amp;quot;: {
            &amp;quot;record&amp;quot;: {
                &amp;quot;id&amp;quot;: &amp;quot;dd21a094-e78a-11ee-ac3a-02d786a79729&amp;quot;,
                &amp;quot;name&amp;quot;: &amp;quot;&amp;quot;,
                &amp;quot;first_name&amp;quot;: &amp;quot;&amp;quot;,
                &amp;quot;title&amp;quot;: &amp;quot;Recruiting Manager_&amp;quot;,
                &amp;quot;sync_key&amp;quot;: &amp;quot;sync_key_test&amp;quot;
            }
        },
        &amp;quot;headers&amp;quot;: [],
        &amp;quot;status&amp;quot;: 200,
        &amp;quot;status_text&amp;quot;: &amp;quot;OK&amp;quot;
    },
    {
        &amp;quot;contents&amp;quot;: {
            &amp;quot;record&amp;quot;: []
        },
        &amp;quot;headers&amp;quot;: [],
        &amp;quot;status&amp;quot;: 200,
        &amp;quot;status_text&amp;quot;: &amp;quot;OK&amp;quot;
    }
]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Enhance the &amp;quot;Prune Database on 1st of Month&amp;quot; Scheduler with time delay criteria&lt;/h3&gt;
&lt;p&gt;Currently the &amp;ldquo;Prune Database on 1st of Month&amp;ldquo; deletes everything from the database that has the column &amp;ldquo;deleted&amp;ldquo; equal to 1, in this release, we are adding a time sensitive&lt;span&gt;&amp;nbsp;criteria in the query for pruning the database&amp;nbsp;using date_modified, something like:&lt;code&gt;&amp;nbsp;SELECT&amp;nbsp;id&amp;nbsp;FROM table&amp;nbsp;WHERE deleted = 1 AND date_modified &amp;lt; today() - pruneDelay_24h&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;:&amp;nbsp;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Restricting Access to Admins Only&lt;/h3&gt;
&lt;p&gt;In this release, we have added a restriction at the API&amp;nbsp;layer for Admin/Developer Only to access the following modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shippers&lt;/li&gt;
&lt;li&gt;TaxRates&lt;/li&gt;
&lt;li&gt;Releases&lt;/li&gt;
&lt;li&gt;Styleguide&lt;/li&gt;
&lt;li&gt;Roles&lt;/li&gt;
&lt;li&gt;Teams&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Improve TeamSecurity subqueries in ProspectList module&lt;/h3&gt;
&lt;p&gt;In this release,&amp;nbsp;we have improved the subquery mechanism used on&amp;nbsp;&lt;span&gt;/modules/ProspectLists/ProspectList.php to use&amp;nbsp;&lt;code&gt;\SugarBean::addVisibilityWhere&lt;/code&gt;&amp;nbsp;to use an optimized version of queries and make it possible to disable TeamSecurity or apply custom visibility if needed.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Mobile Metadata Improvements&lt;/h3&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;activity-card-content&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-definition&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-detail&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-header&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-timeline&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Fix: Portal users can submit cases if disabled with an active token&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;This functionality has been&lt;span&gt;&amp;nbsp;&lt;/span&gt;backported to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;13.0.4&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;14.0.1&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;releases.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Introducing SecureSmarty&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In this release, we are&amp;nbsp;introducing&amp;nbsp;&lt;code&gt;SecureSmarty&lt;/code&gt;&amp;nbsp;a safer replacement to&amp;nbsp;&lt;code&gt;Smarty,&amp;nbsp;SugarPdfSmarty,&lt;/code&gt;&amp;nbsp;&lt;code&gt;Sugar_Smarty&lt;/code&gt;. This new class enforces usage of secure Smarty settings preventing the use of unsecure functions that could potentially endanger your instance.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;After upgrade, when this feature is enabled (see&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;]&lt;/code&gt;), PackageScanner will not allow those classes (&lt;code&gt;Smarty,&amp;nbsp;SugarPdfSmarty,&lt;/code&gt;&amp;nbsp;&lt;code&gt;Sugar_Smarty&lt;/code&gt;) to be used in MLP/Addons and they&amp;#39;ll have to be replaced with&amp;nbsp;&lt;code&gt;SecureSmarty&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Note: This feature is disabled in&amp;nbsp;&lt;code&gt;14.1&lt;/code&gt;&amp;nbsp;and will automatically enabled in&amp;nbsp;&lt;code&gt;14.2&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sanitizing data&amp;nbsp;in templates&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In this release, v&lt;/span&gt;ariables in templates&amp;nbsp;will be escaped according to the context they are used.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Smarty has modifiers to escape variables, most of the variables are already escaped&lt;/li&gt;
&lt;li&gt;Hanldebars escapes variables by default if you use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{{&lt;/code&gt;. Places that use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{{{&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;should be sanitized with&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{sanitize}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;XTemplate doesn&amp;rsquo;t have any functionality to escape variables and uses them as is. We&amp;nbsp;are&amp;nbsp;escaping data before passing to the template and/or introduce modifiers&amp;nbsp;when necessary/&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Core Security Updates&lt;/h3&gt;
&lt;p&gt;As part of our ongoing efforts to keep Sugar clean, fast, reliable, and most importantly secure, we have updated&amp;nbsp;Sugar Core code in different areas of the application such as Package Scanner, Module Installer, UI rendering, Handlebar templates, File Uploads and Imports.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Core&amp;nbsp;readiness to PHP 8.3&lt;/h3&gt;
&lt;p&gt;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&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="/dev-club/w/dev-tutorials/819/automated-php-compatibility-tool"&gt;Rector&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for this work.&lt;/p&gt;
&lt;h2 id="mcetoc_1f77psegv7"&gt;Denylist Updates&lt;/h2&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;span&gt;In this release, we are adding the following&amp;nbsp;functions to the PackageScanner&amp;#39;s denylist:&lt;/span&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;show_source()&lt;/code&gt;&lt;/li&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;php_strip_whitespace()&lt;/code&gt;&lt;/li&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;highlight_file()&amp;nbsp;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;p&gt;&lt;span&gt;When&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;]&lt;/code&gt;), gets enabled, these classes will be added to the PackageScanner&amp;#39;s denylist:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;Smarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;SugarPdfSmarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;Sugar_Smarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Sugar Q3 2024, Sugar 14.1&lt;/div&gt;
</description></item><item><title>Sugar 14.1 (Q3 2024) Customization Guide</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide/revision/2</link><pubDate>Fri, 12 Jul 2024 13:31:09 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:06fade0c-5fd1-46be-80e5-9004b949ce64</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide#comments</comments><description>Revision 2 posted to Dev Tutorials by Rafael Fernandes on 7/12/2024 1:31:09 PM&lt;br /&gt;
&lt;h1 class="name"&gt;Sugar 14.1 (Q3 2024) Customization Guide&lt;/h1&gt;
&lt;div class="content"&gt;
&lt;div class="content"&gt;
&lt;p&gt;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&amp;nbsp;&lt;span&gt;14.1 (Q&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2024) that could cause an immediate impact on Sugar customizations and integrations built for earlier Sugar versions.&lt;/p&gt;
&lt;p&gt;Please check out the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="/dev-club/m/event-recaps/2801"&gt;Q3 2024 Developer Webinar recording&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for more developer highlights.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;For Admin and End User release notes, please visit the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://support.sugarcrm.com/SmartLinks/Release_Notes/14.1.0_Release_Notes/"&gt;Sugar 14.1.0 Release Notes&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1ff80k9i32"&gt;User Experience Updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;AI Summary Dashlet for Opportunities and Cases&lt;/h3&gt;
&lt;p&gt;We are very excited to introduce&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;AI-driven&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;summarization capabilities to Sugar on Opportunities and Cases modules.&lt;/p&gt;
&lt;p&gt;This will empower users to extract key insights and information from their CRM data more efficiently by adding&lt;span class="TextRun SCXW260305411 BCX0" lang="EN-US" data-contrast="auto"&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&amp;nbsp;new&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SpellingErrorV2Themed SCXW260305411 BCX0"&gt;dashlets&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&amp;nbsp;to display those summaries&amp;nbsp;in those modules.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;Th&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;is&lt;/span&gt;&lt;span class="NormalTextRun SCXW260305411 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;feature leverages GPT (Generative Pre-trained Transformer) technology to generate concise and contextually relevant summaries, sentiment etc. of record details.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW260305411 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;Any users with access to Opportunities or Cases can view the dashlet once it is added (see note).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;The initial summary will be generated when an opportunity or case record is opened.&amp;nbsp; 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&amp;rsquo;s most advanced LLM. All data used by the summary is anonymized by SugarCRM before sharing it with OpenAI.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&amp;nbsp;Extra license/cost is required to enable AI Dashlet data.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Static Conversion Rates on Quotes&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;,&amp;nbsp;we&amp;#39;re introducing a concept of Locking&amp;nbsp;Currency Rate in Quote and Quote Line Items (QLIs). Prior to this version,&amp;nbsp;the conversion rate remains dynamic unless the quote is in a closed stage (&lt;span class="TextRun SCXW88795868 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW88795868 BCX0"&gt;Closed Dead, Closed Lost, Closed Accepted&lt;/span&gt;&lt;/span&gt;), furthermore&amp;nbsp;&lt;span class="TextRun SCXW236130893 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;closing the Quote only&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;maintained&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the currency rate for the original line items. If&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;new items&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;were added later, and the conversion rate had changed in admin&amp;gt;currencies, the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;new items&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;would adopt the latest conversion rate, thus&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;failing to ensure&lt;/span&gt;&lt;span class="NormalTextRun SCXW236130893 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;a truly static rate.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="TextRun SCXW7993086 BCX0" lang="EN-US" data-contrast="none"&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;This solution involved adding a new checkbox field, &amp;quot;Lock Currency Rates.&amp;quot; This field, along with the existing Currency Rate field,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;will be displayed as a field set&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;in the Record View and Record View&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Dashlet&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;layout&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(available to be added in different layouts)&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;, where users typically work with Quotes and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Quoted&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;Line&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Items. When users select the &amp;quot;Lock Currency Rates&amp;quot; field, the Quote will store the current conversion rates for existing QLIs, and any future QLIs created will&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;maintain&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the same conversion rate, even if it changes in admin&amp;gt;currencies. If users choose to unlock the &amp;quot;Lock Currency Rate&amp;quot; field, all related RLIs will update to reflect the most recent&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;conversion&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW7993086 BCX0"&gt;rate in admin&amp;gt;currencies.&lt;/span&gt;&lt;/span&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;The addition of this new field allows admins and users to lock currency conversion rates without having to close the Quote, thereby preserving the&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;accurate&lt;/span&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Quote Stage.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="EOP SCXW236130893 BCX0"&gt;&lt;span class="EOP SCXW7993086 BCX0"&gt;&lt;span class="NormalTextRun SCXW106199403 BCX0"&gt;Users will be notified through CONFIRM dialogs when enabling/disabling Lock conversion rate checkbox.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Making Chart Colors consistent in Sugar&lt;/h3&gt;
&lt;p&gt;In this release, we have implemented a consistent way to assign colors in Sugar. The idea is to&amp;nbsp;use consistent algorithm to pick colors to be rendered across the application.&lt;/p&gt;
&lt;p&gt;&lt;span data-contrast="none"&gt;Every dropdown field, except those dynamically generated &amp;ndash; gets a color from the pallet for each value. That color will be used in any chart that shows the data from this dropdown.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Product Catalog for Serve&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;,&amp;nbsp;we are enabling Product Catalog for Serve license users, they&lt;span class="TextRun SCXW50559475 BCX0" lang="EN-US" data-contrast="auto"&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;&amp;nbsp;can easily access and manage product&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;catalog&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="NormalTextRun SCXW50559475 BCX0"&gt;making everything more organized and accessible.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Accessibility&amp;nbsp;Improvements&lt;/h3&gt;
&lt;p&gt;In this&amp;nbsp;&lt;span&gt;release&lt;/span&gt;, we&amp;#39;ve enhanced Sugar to provide greater accessibility to the user interface, including improvements to VoiceOver and keyboard accessibility commands.&lt;/p&gt;
&lt;p&gt;Sugar is now injecting some javascript&amp;nbsp;attributes to the HTML necessary for VoiceOver and Keyboard to properly work with newer browser versions.&lt;/p&gt;
&lt;p&gt;Some HTML elements were modified to include such attributes directly in their handlebar templates where injecting wasn&amp;#39;t feasible.&lt;/p&gt;
&lt;p&gt;Sugar areas that are part of these improvements are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Service Consoles&lt;/li&gt;
&lt;li&gt;Dropdowns&lt;/li&gt;
&lt;li&gt;Subpanels and its options (+ and More)&lt;/li&gt;
&lt;li&gt;Table Headers (sorted tables)&lt;/li&gt;
&lt;li&gt;Alerts (warning, success, errors)&lt;/li&gt;
&lt;li&gt;List Views (sorting arrow icon)&lt;/li&gt;
&lt;li&gt;Column Descriptions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl10"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1givqvoho2"&gt;&lt;span&gt;&lt;span class="NormalTextRun SCXW249156672 BCX0"&gt;&lt;/span&gt;&lt;/span&gt;Sugar REST API updates&lt;/h3&gt;
&lt;p&gt;This Sugar release introduces REST&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;v11_25&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;Retrieve record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;GET &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;GET &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;PATCH/PUT/UPSERT&amp;nbsp;record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to&amp;nbsp;patch a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;PATCH &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;PATCH &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1gjpkca900"&gt;Delete&amp;nbsp;record with given sync_key from the query params&lt;/h3&gt;
&lt;p&gt;Allows the user to retrieve a record by sync_key using query params instead of endpoint URL.&lt;/p&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;DELETE &amp;lt;sugar instance&amp;gt;/rest/v11_25/&amp;lt;module&amp;gt;/sync_key?sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1ff80k9i33"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class="content-scrollable-wrapper"&gt;
&lt;pre&gt;DELETE &amp;lt;sugar instance&amp;gt;/rest/v11_25/integrate/&amp;lt;module&amp;gt;/?sync_key_field_name=&amp;lt;sync key field name&amp;gt;&amp;amp;sync_key_field_value=&amp;lt;sync key value&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1hv2v4rq60"&gt;&lt;code&gt;&lt;/code&gt;&lt;/h3&gt;
&lt;h2 id="mcetoc_1ff80k9i33"&gt;Configurability&amp;nbsp;updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1f7c87abe2"&gt;&lt;/h3&gt;
&lt;h3 id="mcetoc_1f7c8nhce4"&gt;&lt;strong&gt;Studio&lt;/strong&gt;&lt;/h3&gt;
&lt;h4&gt;&amp;quot;processed&amp;quot; not allowed as custom field in Moduie Builder&lt;/h4&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;p&gt;In this release, we are adding&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;processed&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;word&amp;nbsp;to the list of reserved words in Sugar.&lt;/p&gt;
&lt;p&gt;You will not be able to use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;processed&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;as a field name in Module Builder when creating a new module.&lt;/p&gt;
&lt;p&gt;For reference,&amp;nbsp;this is the list of disallowed fields in Module Builder:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;ID_C&lt;/li&gt;
&lt;li&gt;PARENT_NAME&lt;/li&gt;
&lt;li&gt;PARENT_ID&lt;/li&gt;
&lt;li&gt;* PROCESSED&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 id="mcetoc_1f77psegv7"&gt;Sugar Config Settings&lt;/h3&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Setting Name&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Override Example&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;moduleInstaller.features.enableRectorModuleScanner&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;span&gt;$sugar_config['moduleInstaller']['packageScan'] = true;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner'] = true;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Enables scanning of code of MLPs before installation for compatibility with modern versions of PHP. This occurs as one of the stages in Package Scanner, 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.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;pruneDelay&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;86400000&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$sugar_config[&amp;#39;&lt;/span&gt;&lt;span&gt;pruneDelay&amp;#39;] =&amp;nbsp;10&lt;/span&gt;&lt;span&gt;6400000&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Adds a delay to the Prune job to take into account the date_modified &amp;lt; today()-pruneDelay used to select the records to be deleted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;moduleInstaller.features.enforceSecureSmarty&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;false&lt;/td&gt;
&lt;td&gt;&lt;span&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;] = true;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;When enabled it enforces usage of SecureSmarty instead of Smarty and Sugar_Smarty. SecureSmarty enforces usage of secure Smarty settings.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="mcetoc_1f77psegvb"&gt;Removed Functions / Libraries / Features&lt;/h2&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Upgrade Scripts&lt;/h3&gt;
&lt;p&gt;Over time our upgrade scripts have accumulated a lot of steps that are likely no longer necessary to to it&amp;#39;s version restrictions. In this release, we&amp;#39;ve removed the deprecated/outdated upgrade scripts.&lt;/p&gt;
&lt;h2 id="mcetoc_1g4djj0su0"&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1f77psegvl"&gt;Platform Updates&lt;/h2&gt;
&lt;h3 id="mcetoc_1gqa6vaoc8"&gt;&lt;span&gt;Add rector scanner step into PackageScanner during MLP installation&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;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 ModuleLoader.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This feature&amp;nbsp;relies on&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features']['enableRectorModuleScanner']&lt;/code&gt;&amp;nbsp;which is&amp;nbsp;&lt;strong&gt;disabled&lt;/strong&gt;&amp;nbsp;by default until further notice.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;ExternalResourceClient&amp;nbsp;Enhancements&lt;/h3&gt;
&lt;p&gt;In this release,&amp;nbsp;we&amp;#39;ve added&amp;nbsp;t&lt;span&gt;he missing pieces&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;you need to make HTTP requests from Sugar without relying on third-party frameworks like curl, guzzle, or any other transport client.&lt;/p&gt;
&lt;p&gt;The features we added were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Base Uri:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The base URI of the client that is merged into relative URIs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;
&amp;lt;?php
// Base URI
$baseUri = &amp;#39;https://httpbin.org/anything/&amp;#39;;
$path = &amp;#39;foo/bar&amp;#39;;
$erc = (new ExternalResourceClient())-&amp;gt;setBaseUri($baseUri);
$response = $erc-&amp;gt;get($path); // Sends request to https://httpbin.org/anything/foo/bar
?&amp;gt;

&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;File downloads&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The external file may be downloaded into the directory returned by&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;UploadStream::getDir()&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;call (`upload` by default)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$url = &amp;#39;https://httpbin.org/image/png&amp;#39;; // Url of file to download
$filename = &amp;#39;img.png&amp;#39;; // Local filename
$response = $erc-&amp;gt;download($url, $filename); // Downloads file from $url into `upload` as $filename
?&amp;gt;

&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Trusted external resources.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The new method `&lt;code&gt;ExternalResourceClient::trustTo(...$hosts)&lt;/code&gt;` has been added to prevent issues with firewalls.&lt;/li&gt;
&lt;li&gt;The specified hostnames will not be translated to the corresponding IP addresses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;the IP of the target hostname should not belong to the private network (or it should be allowed via&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;$sugar_config['security']['private_ips']).&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="php"&gt;&amp;lt;?php
$erc-&amp;gt;trustTo(&amp;#39;mytrusted.website.com&amp;#39;);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;This functionality has been backported to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;13.0.4&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;14.0.1&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;releases.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Integrate (UPSERT) API Enhancements&lt;/h3&gt;
&lt;p&gt;In this release, we have improved our Integrate API endpoints to support&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;sync_keys&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;with&amp;nbsp;special characters such as forward slash (&amp;quot;/&amp;quot;) 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 &amp;quot;/&amp;quot;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GET:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate api
curl --location --request 
  GET &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Contacts/?&amp;#39; \
      &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 
  
// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  GET &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Contacts/sync_key?&amp;#39;\
  &amp;#39;sync_key_field_value=329bc7ec-f745-11ee-8f5b-021b212599db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PATCH/PUT (a.k.a UPSERT):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate API (PATH or PUT) works
curl --location --request 
  PATCH &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Accounts/?&amp;#39;\
  &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  --data-raw &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;rafa test 1&amp;quot;}&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 

// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  PATCH &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Accounts/sync_key&amp;#39; \
  &amp;#39;?sync_key_field_value=123db%2F002&amp;#39; \
  --data-raw &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;rafa test 1&amp;quot;}&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DELETE:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="batchfile"&gt;// using integrate API 
curl --location --request 
  DELETE &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/integrate/Accounts/?&amp;#39; \
  &amp;#39;sync_key_field_name=sync_key&amp;amp;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; 

// using module &amp;#39;sync_key&amp;#39;
curl --location --request 
  DELETE &amp;#39;https://&amp;lt;instance&amp;gt;/rest/v11_25/Accounts/sync_key?&amp;#39; \
  &amp;#39;sync_key_field_value=123db%2F002&amp;#39; \
  -H &amp;#39;Content-Type: application/json&amp;#39; &lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Those improvements were &amp;quot;added&amp;quot; to the current implementation therefore what&amp;#39;s currently available is still valid.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Bulk API Enhancements&lt;/h3&gt;
&lt;p&gt;In this release, we have also improved how we return data from our&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;bulk&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;endpoint where now you can specify which fields you would like to return as part of the bulk endpoint when it is successful.&lt;/p&gt;
&lt;p&gt;In the following example, notice that we&amp;#39;d like to get back few&amp;nbsp;extra fields from the record itself, we can by specifying an extra &amp;quot;fields&amp;quot; attribute in the payload. if [&amp;#39;&lt;code&gt;fields&lt;/code&gt;&amp;#39;] param provided (it is optional) in the request body (in &amp;#39;&lt;code&gt;data&lt;/code&gt;&amp;#39; 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.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="javascript"&gt;{&amp;quot;requests&amp;quot;:[
    {
        &amp;quot;url&amp;quot;:&amp;quot;v11_25/integrate/Contacts/sync_key/sync_key_test&amp;quot;,
        &amp;quot;method&amp;quot;:&amp;quot;PATCH&amp;quot;,
        &amp;quot;data&amp;quot;:{&amp;quot;title&amp;quot;:&amp;quot;Recruiting Manager_&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;2&amp;quot;, &amp;quot;fields&amp;quot;:[&amp;quot;id&amp;quot;,&amp;quot;sync_key&amp;quot;,&amp;quot;name&amp;quot;,&amp;quot;title&amp;quot;, &amp;quot;first_name&amp;quot;]}
    },
        {
        &amp;quot;url&amp;quot;:&amp;quot;v11_25/integrate/Accounts/sync_key/sync_key_test&amp;quot;,
        &amp;quot;method&amp;quot;:&amp;quot;PATCH&amp;quot;,
        &amp;quot;data&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;NEw Name&amp;quot;, &amp;quot;fields&amp;quot;:&amp;quot;1&amp;quot;}
    }
]
}

//===== RESPONSE
[
    {
        &amp;quot;contents&amp;quot;: {
            &amp;quot;record&amp;quot;: {
                &amp;quot;id&amp;quot;: &amp;quot;dd21a094-e78a-11ee-ac3a-02d786a79729&amp;quot;,
                &amp;quot;name&amp;quot;: &amp;quot;&amp;quot;,
                &amp;quot;first_name&amp;quot;: &amp;quot;&amp;quot;,
                &amp;quot;title&amp;quot;: &amp;quot;Recruiting Manager_&amp;quot;,
                &amp;quot;sync_key&amp;quot;: &amp;quot;sync_key_test&amp;quot;
            }
        },
        &amp;quot;headers&amp;quot;: [],
        &amp;quot;status&amp;quot;: 200,
        &amp;quot;status_text&amp;quot;: &amp;quot;OK&amp;quot;
    },
    {
        &amp;quot;contents&amp;quot;: {
            &amp;quot;record&amp;quot;: []
        },
        &amp;quot;headers&amp;quot;: [],
        &amp;quot;status&amp;quot;: 200,
        &amp;quot;status_text&amp;quot;: &amp;quot;OK&amp;quot;
    }
]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Enhance the &amp;quot;Prune Database on 1st of Month&amp;quot; Scheduler with time delay criteria&lt;/h3&gt;
&lt;p&gt;Currently the &amp;ldquo;Prune Database on 1st of Month&amp;ldquo; deletes everything from the database that has the column &amp;ldquo;deleted&amp;ldquo; equal to 1, in this release, we are adding a time sensitive&lt;span&gt;&amp;nbsp;criteria in the query for pruning the database&amp;nbsp;using date_modified, something like:&lt;code&gt;&amp;nbsp;SELECT&amp;nbsp;id&amp;nbsp;FROM table&amp;nbsp;WHERE deleted = 1 AND date_modified &amp;lt; today() - pruneDelay_24h&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;:&amp;nbsp;&lt;span&gt;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.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Restricting Access to Admins Only&lt;/h3&gt;
&lt;p&gt;In this release, we have added a restriction at the API&amp;nbsp;layer for Admin/Developer Only to access the following modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shippers&lt;/li&gt;
&lt;li&gt;TaxRates&lt;/li&gt;
&lt;li&gt;Releases&lt;/li&gt;
&lt;li&gt;Styleguide&lt;/li&gt;
&lt;li&gt;Roles&lt;/li&gt;
&lt;li&gt;Teams&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Improve TeamSecurity subqueries in ProspectList module&lt;/h3&gt;
&lt;p&gt;In this release,&amp;nbsp;we have improved the subquery mechanism used on&amp;nbsp;&lt;span&gt;/modules/ProspectLists/ProspectList.php to use&amp;nbsp;&lt;code&gt;\SugarBean::addVisibilityWhere&lt;/code&gt;&amp;nbsp;to use an optimized version of queries and make it possible to disable TeamSecurity or apply custom visibility if needed.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Mobile Metadata Improvements&lt;/h3&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;activity-card-content&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-definition&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-detail&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-card-header&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;activity-timeline&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Fix: Portal users can submit cases if disabled with an active token&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;This functionality has been&lt;span&gt;&amp;nbsp;&lt;/span&gt;backported to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;13.0.4&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;14.0.1&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;releases.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Introducing SecureSmarty&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In this release, we are&amp;nbsp;introducing&amp;nbsp;&lt;code&gt;SecureSmarty&lt;/code&gt;&amp;nbsp;a safer replacement to&amp;nbsp;&lt;code&gt;Smarty,&amp;nbsp;SugarPdfSmarty,&lt;/code&gt;&amp;nbsp;&lt;code&gt;Sugar_Smarty&lt;/code&gt;. This new class enforces usage of secure Smarty settings preventing the use of unsecure functions that could potentially endanger your instance.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;After upgrade, when this feature is enabled (see&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;]&lt;/code&gt;), PackageScanner will not allow those classes (&lt;code&gt;Smarty,&amp;nbsp;SugarPdfSmarty,&lt;/code&gt;&amp;nbsp;&lt;code&gt;Sugar_Smarty&lt;/code&gt;) to be used in MLP/Addons and they&amp;#39;ll have to be replaced with&amp;nbsp;&lt;code&gt;SecureSmarty&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Note: This feature is disabled in&amp;nbsp;&lt;code&gt;14.1&lt;/code&gt;&amp;nbsp;and will automatically enabled in&amp;nbsp;&lt;code&gt;14.2&lt;/code&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sanitizing data&amp;nbsp;in templates&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;In this release, v&lt;/span&gt;ariables in templates&amp;nbsp;will be escaped according to the context they are used.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Smarty has modifiers to escape variables, most of the variables are already escaped&lt;/li&gt;
&lt;li&gt;Hanldebars escapes variables by default if you use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{{&lt;/code&gt;. Places that use&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{{{&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;should be sanitized with&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;code&gt;{sanitize}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;XTemplate doesn&amp;rsquo;t have any functionality to escape variables and uses them as is. We&amp;nbsp;are&amp;nbsp;escaping data before passing to the template and/or introduce modifiers&amp;nbsp;when necessary/&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Core Security Updates&lt;/h3&gt;
&lt;p&gt;As part of our ongoing efforts to keep Sugar clean, fast, reliable, and most importantly secure, we have updated&amp;nbsp;Sugar Core code in different areas of the application such as Package Scanner, Module Installer, UI rendering, Handlebar templates, File Uploads and Imports.&lt;/p&gt;
&lt;h3 id="mcetoc_1gb30ctl1e"&gt;Sugar Core&amp;nbsp;readiness to PHP 8.3&lt;/h3&gt;
&lt;p&gt;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&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="/dev-club/w/dev-tutorials/819/automated-php-compatibility-tool"&gt;Rector&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for this work.&lt;/p&gt;
&lt;h2 id="mcetoc_1f77psegv7"&gt;Denylist Updates&lt;/h2&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;span&gt;In this release, we are adding the following&amp;nbsp;functions to the PackageScanner&amp;#39;s denylist:&lt;/span&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;show_source()&lt;/code&gt;&lt;/li&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;php_strip_whitespace()&lt;/code&gt;&lt;/li&gt;
&lt;li class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;code&gt;highlight_file()&amp;nbsp;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="code-block sc-ezYOhE gBYPJJ"&gt;
&lt;p&gt;&lt;span&gt;When&amp;nbsp;&lt;code&gt;$sugar_config['moduleInstaller']['features'][&amp;lsquo;enforceSecureSmarty&amp;rsquo;]&lt;/code&gt;), gets enabled, these classes will be added to the PackageScanner&amp;#39;s denylist:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;Smarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;SugarPdfSmarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;Sugar_Smarty&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: Sugar Q3 2024, Sugar 14.1&lt;/div&gt;
</description></item><item><title>Sugar 14.1 (Q3 2024) Customization Guide</title><link>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide/revision/1</link><pubDate>Mon, 01 Jul 2024 18:21:54 GMT</pubDate><guid isPermaLink="false">5c521d64-519d-47a6-9065-134618b211bf:06fade0c-5fd1-46be-80e5-9004b949ce64</guid><dc:creator>Rafael Fernandes</dc:creator><comments>https://sugarclub.sugarai.com/dev-club/w/dev-tutorials/957/sugar-14-1-q3-2024-customization-guide#comments</comments><description>Revision 1 posted to Dev Tutorials by Rafael Fernandes on 7/1/2024 6:21:54 PM&lt;br /&gt;
&lt;p&gt;Sugar 14.1 (Q3 2024) Customization Guide&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>